C++ 复制c++;抽象类
好的,这里有一些代码C++ 复制c++;抽象类,c++,arrays,inheritance,C++,Arrays,Inheritance,好的,这里有一些代码 #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()
#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.
}
#包括
#包括
使用名称空间std;
甲级
{
公众:
虚拟空执行()
{
cout克隆());
aclasse2.push_back(aclasses[1]->clone());
//现在我的问题显现出来了
对于每个(ACLASSE2中的A*A)
a->Execute();
//Execute从原始类A调用两次。
}
您需要提供一个虚拟副本构造函数——通常这是一个名为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
).您需要提供一个虚拟副本构造函数——通常这是一个名为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
否则)。您有了一个(…)
新的复制构造函数。所调用的是a
的复制构造函数(由编译器隐式创建
您需要的是一个克隆
方法。请参阅。它重述了优秀书籍中的相应内容。下面是最终解决方案的无耻副本,它还展示了如何很好地使用来避免问题
更新 一点解释。克隆人的基本思想与这里的其他优秀答案相同 现在,使用克隆时,您会面临分割对象的危险。例如,如果从
A
派生的某个对象忘记实现自己的clone
方法,那么调用A*A=d->clone()
将不会返回完整的d
对象(假设d
是A
的后代)
NVI的习惯用法是将公共接口与虚拟接口分开。因此,在本例中,clone
是public
,而不是virtual
。它调用protectedvirtual
方法,doClone
,该方法执行实际的克隆,并且还实现了哪些派生对象。由于拆分,一个的复制构造函数(由编译器隐式创建)
您需要的是一个克隆
方法。请参阅。它重述了优秀书籍中的相应内容。下面是最终解决方案的无耻副本,它还展示了如何很好地使用来避免问题
更新
一点解释。克隆人的基本思想与这里的其他优秀答案相同
现在,使用克隆时,您会面临分割对象的危险。例如,如果从A
派生的某个对象忘记实现自己的clone
方法,那么调用A*A=d->clone()
将不会返回完整的d
对象(假设d
是A
的后代)
NVI的习惯用法是将公共接口与虚拟接口分开。因此,在本例中,clone
是public
,而不是virtual
。它调用protectedvirtual
方法,doClone
,该方法执行实际的克隆,并且还实现了哪些派生对象。由于拆分,e> clone
方法可以验证克隆对象的类型是否与原始对象的类型匹配。我认为您会混淆类和对象,即这些类的实例
您的容器aclasses
存储指向现有对象的指针。您可以在许多不同的容器中多次使用同一指针,这不是所谓的克隆。我认为您混淆了类和对象,即这些类的实例
您的容器aclasses
存储指向现有对象的指针。您可以在许多不同的容器中多次使用同一指针,这不是所谓的克隆。通过虚拟克隆()
基类中的方法,该方法将创建适当类型的新对象:
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
}
struct base{
virtual~base(){}//不要忘记虚拟析构函数
虚拟基*克隆()常量{
返回新的基(*此);
}
};
派生结构:基{
虚拟派生的*clone()常量{//返回类型为共同变量
返回新的派生(*此);
}
};
int main(){
标准::自动测试b1(新衍生);
std::auto_ptr b2(b1->clone());//将创建一个派生对象
}
通过基类中的虚拟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
}
struct base{
virtual~base(){}//不要忘记虚拟析构函数
虚拟基*克隆()常量{
返回新的基(*此);
}
};
派生结构:基{
虚拟派生的*clone()常量{//返回类型为共同变量
返回新的派生(*此);
}
};
int main(){
标准::自动测试b1(新衍生);
std::auto_ptr b2(b1->clone());//将创建一个派生对象
}
void Main
=>int Main
。我在这里没有看到抽象类(:为什么要创建带有指针的deque
-s?是否有som