重置派生类对象

时间:2017-06-30 09:51:21

标签: c++ c++11

我想在下面做到这样的事情:

class A {
public:
    virtual void reset() {
    // 1). if there's no override to this function,
    // then whatever derived from A should get reset
    // to its constructed state, e.g. if B derives from
    // A, then *this = B();
    // 2). if there is an override to reset in the derived 
    // class, call the reset in the derived class
    }
};
class B: public A {
public:
    B() { std::cout<<"reset B"<<std::endl; }
    // no override of reset() here
}; 
class C: public A {
public:
    void reset() override {
        std::cout<<"reset C"<<std::endl;
    }
};

N.B。 A不知道哪个类将从中派生,但是无论从哪个派生出来,如果在该派生类中没有reset()覆盖,调用A :: reset()应该重置派生类反对它的构造状态,即

A* a = new B();
a->reset(); // -> this equals to *a = B();

但是,如果在派生类中重写了reset(),则调用A :: reset()应该调用重写的reset(),即

A* a = new C();
a->reset(); // -> this should call C::reset()

2 个答案:

答案 0 :(得分:2)

正如我在评论中所提到的,可以在CRTP的另一级继承的帮助下解决:

// The base class is just an abstract interface class
struct A
{
    virtual void reset() = 0;
};

template<typename T>
struct realA : public A
{
    void reset() override
    {
        *this = T();
    }
}

class B : public realA<B>
{
    ... whatever you need here...
};

现在你可以做到

A* a = new B;
a->reset();

它应该可以正常工作。

您拥有(现在是抽象的)基类A,其中包含所需的接口。然后你有了模板类realA,其中包含你在A类变体中的实现,最值得注意的是reset函数实现。然后是类似B(和C及其他)的类,它们继承自realA而不是A

答案 1 :(得分:0)

除了公认的答案外,还有另一种方法。

p (char[12])buffer

上述问题是只能使用公共成员函数。