Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 复制c++;抽象类_C++_Arrays_Inheritance - Fatal编程技术网

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
,该方法执行实际的克隆,并且还实现了哪些派生对象。由于拆分,e> clone方法可以验证克隆对象的类型是否与原始对象的类型匹配。

您有一个新的(…)方法。调用的是
一个
的复制构造函数(由编译器隐式创建)

您需要的是一个
克隆
方法。请参阅。它重述了优秀书籍中的相应内容。下面是最终解决方案的无耻副本,它还展示了如何很好地使用来避免问题


更新 一点解释。克隆人的基本思想与这里的其他优秀答案相同

现在,使用克隆时,您会面临分割对象的危险。例如,如果从
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