【问题标题】:Invoke the copy construction of a derived class from a pointer to the base class?从指向基类的指针调用派生类的复制构造?
【发布时间】:2015-06-01 01:29:05
【问题描述】:

我有

1- class A {int m;};
2- class B: public A
{float n;};
3- class C: public A
{string n;};

我将A类的所有实例都存储在

vector <class A*> myInstansesofA;

它被存储为一个指针,因为我根据一些 if 语句动态创建它们

if (some condition)
{
      A* newA = new B();
      myInstancesofA.push_back(newA );
}
else
{
      A* newA = new C();
      myInstancesofA.push_back(newA );
}

现在我需要创建矢量的精确副本。使用新的指针集,但数据的精确副本。

问题在于将 A 的每个实例(实际上是 B 和 C)的数据复制到新向量。

我尝试了以下方法,但它不起作用。

for (vector<A*>::const_iterator it = myInstancesofA.begin(); it != myInstancesofA.end(); ++it)
    {
        A* newA = new A(*(*it));
        myInstancesofA.push_back(newA );
    }

我怀疑发生此错误是因为“new A”仅调用类型 A 的复制构造函数,而不调用 B 或 C(我调试并发现这种情况正在发生)。

我该如何解决这个问题?

【问题讨论】:

    标签: c++ pointers inheritance copy-constructor dynamic-allocation


    【解决方案1】:

    我相信你不能像那样调用构造函数,并且在 C++ 中没有直接的方法来做类似的事情(对于像 Java 和 C# 这样的反射语言来说,这是非常简单的)。

    一种方法是使用prototype pattern

    class A {
    public:
        virtual A* clone() {
            return new A {...};
        }
    };
    
    class B : public A {
    public:
        A* clone() override {
            return new B {.........};
        }
    };
    
    class C : public A {
    public:
        A* clone() override {
            return new C {.........};
        }
    };
    

    对象本身负责创建自己的克隆。当然在设计上还有很多需要改进的地方,但至少它能让你体验一下。

    【讨论】:

    • 好线索,但有一些小细节:BC 应该从A 派生,并且new B()new B 慢(它需要在之前执行零初始化默认构造) - 没有理由在这里使用它;理想情况下,OP会添加构造函数来设置任何必要的字段并简化为例如return new B(...args...);。最后,对于B::cloneC::clone,最好使用override 而不是virtual
    • @TonyD Gosh 我无法想象我错过了那些明显的东西,修复它们(我想我需要一些咖啡):P for new B() 我不知道你提到的差异,可以导致我要一些资料吗? (对不起,我知道的话题:P)
    • 我也需要一杯咖啡!无论如何,在 C++11 标准 4.3.4/17 中要求“如果省略 new-initializer,则默认初始化对象(8.5);如果不执行初始化,则对象具有不确定的值。——否则, new-initializer 根据 8.5 的初始化规则进行解释,用于直接初始化。”,在 8.5/11 和 /17 下,() 不带参数意味着“值已初始化”,在 8.5/8 中进行了描述,如果存在则首先指定零初始化编译器提供的默认构造函数。
    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多