我想做相同的以下操作来初始化数据成员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}会员。
我说错了吗?如果是这样,我该怎么办?
答案 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
不是抽象基类。它没有任何纯虚函数。