复制c++抽象类
copying c++ abstract classes
好的,这里有一些代码。
#include <iostream>
#include <deque>
using namespace std;
class A
{
public:
virtual void Execute()
{
cout << "Hello from class A" << endl;
}
};
class B: public A
{
public:
void Execute()
{
cout << "Hello from class B" << endl;
}
};
void Main()
{
deque<A *> aclasses = deque<A*>(0);
deque<A *> aclasses2 = deque<A*>(0);
A a1 = A();
B b1 = B();
aclasses.push_back(&a1);
aclasses.push_back(&b1);
aclasses[0]->Execute();
aclasses[1]->Execute();
//Now say I want to copy a class from aclasses to aclasses2
//while perserving it's identity and making it a seperate entity, without
//knowing the exact type it is.
aclasses2.push_back(new A(*aclasses[0]));
aclasses2.push_back(new A(*aclasses[1]));
//Now my problem show itself
for each(A * a in aclasses2)
a->Execute();
//Execute is called from the original class A both times.
}
现在你可能会说,你为什么不把第一个德克的指针放进第二个德克呢?虽然我可以,但我需要独立的数据。基本上,我希望能够从第一个deque克隆项目,同时保留那里的身份,并为他们提供自己的数据。
现在是当前的修改版本
#include <iostream>
#include <deque>
using namespace std;
class A
{
public:
virtual void Execute()
{
cout << "Hello from class A" << endl;
}
virtual ~A() {} // don't forget the virtual destructor
virtual A* clone() const {
return new A(*this);
}
};
class B: public A
{
public:
void Execute()
{
cout << "Hello from class B" << endl;
}
virtual B* clone() { // return type is co-variant
return new B( *this );
}
};
void MainRUNNER()
{
deque<A *> aclasses = deque<A*>(0);
deque<A *> aclasses2 = deque<A*>(0);
A a1 = A();
B b1 = B();
aclasses.push_back(&a1);
aclasses.push_back(&b1);
aclasses[0]->Execute();
aclasses[1]->Execute();
//Now say I want to copy a class from aclasses to aclasses2
//while perserving it's identity and making it a seperate entity, without
//knowing the exact type it is.
aclasses2.push_back(aclasses[0]->clone());
aclasses2.push_back(aclasses[1]->clone());
//Now my problem show itself
for each(A * a in aclasses2)
a->Execute();
//Execute is called from the original class A both times.
}
通过基类中的虚拟clone()
方法进行处理的常见模式,该方法将创建适当类型的新对象:
struct base {
virtual ~base() {} // don't forget the virtual destructor
virtual base* clone() const {
return new base(*this);
}
};
struct derived : base {
virtual derived* clone() const { // return type is co-variant
return new derived( *this );
}
};
int main() {
std::auto_ptr<base> b1( new derived );
std::auto_ptr<base> b2( b1->clone() ); // will create a derived object
}
您需要提供一个虚拟副本构造函数——通常这是一个名为clone
的方法——它在每个类中被重写以返回正确的类型:
class A {
virtual A* clone() {
return new A();
}
};
class B : public A {
void A* clone() {
return new B();
}
};
当然,为了复制整个状态,这些方法可以任意复杂。
当然,这会泄露相当多的内存。使用适当的智能指针而不是原始指针(例如,如果编译器支持std::shared_ptr
,则使用boost::shared_ptr
)。
下面有new A(...)
。被调用的是A
的复制构造函数(由编译器.隐式创建)
您想要的是clone
方法。请参见此处。它回顾了优秀的C++编码标准书中的适当项目。下面是最终解决方案的无耻副本,它还展示了NVI习惯用法的良好使用,以避免切片问题。
class A {// …
public:
A* Clone() const { // nonvirtual
A* p = DoClone();
assert( typeid(*p) == typeid(*this) && "DoClone incorrectly overridden" );
return p; // check DoClone's returned type
}
protected:
A( const A& );
virtual A* DoClone() const = 0;
};
class B : public A { // …
public:
virtual B* Clone() const {return new B(*this); }
protected:
B( const B& rhs ) : A( rhs ) {/* … */}
};
更新一点解释。克隆的基本思想与这里的其他优秀答案相同。
现在,有了克隆,就有了对对象进行切片的危险。例如,如果从A
派生的某个对象忘记实现其自己的clone
方法,则对A* a = d->clone()
的调用将不会返回完整的D
对象(假设D
是A
的后代)
NVI习惯用法表示将公共接口与虚拟接口分离。因此,在该示例中,clone
是public
,而不是virtual
。它调用一个protected virtual
方法doClone
,该方法执行实际的克隆,派生对象也实现了该方法。由于分割,clone
方法可以验证克隆对象的类型是否与原始对象的类型匹配。
我认为您混淆了类和对象,即这些类的实例。
容器aclasses
存储指向现有对象的指针。您可以在许多不同的容器中获取同一个指针并多次推动它,这是而不是所谓的克隆。
- 无法创建抽象类的实例
- 用pybind11包装C++抽象类时出错
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 抽象类错误,请参阅声明" "是抽象的
- 将自定义函数传递到基抽象类中以延迟执行
- 将包含抽象类和普通类C++包导出到 Python
- C++:处理抽象类中的错误时出现问题
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 在 C++ 中使用另一个头文件中的抽象类
- ATL::CComContainedObject<contained>: C2259 无法实例化抽象类
- C++:从抽象类重写纯虚拟运算符重载
- 如何创建shared_ptr抽象类的容器
- .h 或.cpp文件中的抽象类或两者兼而有之?
- 从抽象类继承以创建另一个抽象类时,我应该重新声明所有虚函数吗?
- E0322:不允许使用抽象类类型 " " 的对象
- 可视抽象类 c++(错误 LNK 2001:未解析的外部符号)
- 提升 - 类没有名为"序列化"的成员(抽象类)?
- 如何将子类作为函数的参数传递给期望基类,然后将该对象传递到指向这些抽象类对象的指针向量中?
- 对纯抽象类中方法的未定义引用