这是问题,我有一个指向抽象基类的指针向量,这些抽象基类填充了派生对象,如下所示:
class AbstractBase { /* ... */ };
clase Derived1 : public AbstractBase {
Derived1() { }
Derived1( const AbstractBase& abc ) { /* ... */ }
};
/* ... */
vector< AbstratcBase* > lThingies;
const AbstractBase& getThingie(int pos) {
return *lThingies[pos];
}
为了获取元素的副本,我使用派生类“copy constructor”,如下所示:
Derived1 d1 = getThingie(2);
但问题是我不喜欢这样:在构建类“derived42”时没有办法强制执行这个“复制构造函数”,即使你记得它很容易弄错(就像让它成为递归电话一样,发生在我身上)。
我的问题是: 有更好的方法吗?怎么样?
更新
我正在寻找的解决方案的一个“未写”要求是将派生的对象的副本作为局部变量,所以我不要忘记删除他们。
更多信息:
有许多 lThingies ,在运行时,我可以知道(derived1,derived2等)中包含的派生对象是什么,但在编译时却不知道。
答案 0 :(得分:4)
您可以在clone
中创建纯虚拟AbstractBase
函数,该函数返回AbstractBase
指针,并在派生类中覆盖clone
。
<小时/> 严格意见:
虽然(在我看来)这是一种粗略和过时的做法。我建议重新设计,以便首先消除这样做的必要性。
详细阐述我对虚拟构造函数的“粗略和过时”的看法(我确信这会引起争议):
答案 1 :(得分:0)
您知道getThingie
返回Derived1
吗?如果你知道这一点,可能你应该将Derived1
的返回类型和std::vector
中的存储空间更改为Derived1
而不是AbstractBase
。
假设上面的方法不起作用,你可以做一个Derived1 bob = dynamic_cast<Derived1&>(getThingie(...));
,它运行时检查thingy是Derived1
或更多的派生实例,如果是,它会进行转换 - 如果没有,它会引发异常。
如果您不想打扰运行时检查,因为您确定它是Derived1
,只需使用Derived1 bob = static_cast<Derived1&>(getThingy(...));
。
但是,使用具有继承层次结构的类的实际实例是非常值得怀疑的。有许多事情可能出错。
答案 2 :(得分:0)
class A
{
public:
virtual void toto() { std::cout << "Love Java" <<std::endl; }
virtual A&& Duplicate() { return std::move(A()); }
};
class B : public A
{
public:
virtual void toto() { std::cout << "Love C++11" <<std::endl; }
virtual B&& Duplicate() { return std::move(B()); }
};
int main()
{
A *a = new B();;
A&& b(a->Duplicate());
a->toto();
b.toto();
}
在主要内容中,您在堆栈上创建B而不知道其类型。 (在c ++ 11中使用rvalue引用)