如何在构造期间从派生类实例初始化抽象基类数据成员

时间:2014-09-17 20:20:25

标签: c++

我想做相同的以下操作来初始化数据成员my_abc(我怀疑它不起作用):

class ABC { // abstract base class
public:
    virtual ~ABC {};
}

class SomeClass {
public:
    SomeClass(ABC& abc); // argument will actually be instance of derived class
private:
    ABC my_abc; // needs to be set from constructor argument
}

SomeClass::SomeClass(ABC& abc) : my_abc(abc)
{...} // copy construct `my_abc` from argument

我怀疑当ABC的派生类传递给SomeClass构造函数时,这将不起作用,因为不会调用派生类的复制构造函数来初始化{{1}会员。

我说错了吗?如果是这样,我该怎么办?

1 个答案:

答案 0 :(得分:4)

你说,

  

SomeClass(ABC& abc); // argument will actually be instance of derived class

然后,您有一个会员数据

ABC my_abc;

如果使用my_abc初始化abc,您将获得一个不捕获派生类部分的基类对象。查看object slicing的问题。那是你希望完成的吗?我想不是。

正如πάνταῥεῖ的评论中所提到的,你应该存储对基类的引用。

ABC& my_abc_ref;

然后,

SomeClass::SomeClass(ABC& abc) : my_abc_ref(abc) {...}

应该不是问题。

如果要获得输入对象的副本,则需要克隆输入对象并维护克隆对象的生命周期。您可以使用智能指针来完成该任务。

class ABC {
public:
    virtual ~ABC() {}
    virtual ABC* clone() const = 0;
};

#include <memory>

class SomeClass {
public:
    SomeClass(ABC& abc);
private:
    std::unique_ptr<ABC> my_abc;
};

SomeClass::SomeClass(ABC& abc) : my_abc(abc.clone()) {}

这只是显示机制。要创建生产质量代码,您必须对复制和移动构造函数的行为做出策略决策,并复制和移动SomeClass的赋值运算符并适当地实现它们。

<强> PS

发布的类ABC不是抽象基类。它没有任何纯虚函数。