【问题标题】:Double pointers Array of objects - Clone Elements双指针对象数组 - 克隆元素
【发布时间】:2016-04-08 06:37:39
【问题描述】:

我正在尝试掌握继承和深度复制的窍门,但遇到了一些麻烦。 我有 3 个类(1 个 Base 和 2 Derived)如下:

class Base {
protected:
    int id;
public:
    Base(int i) : id(i) {};
    virtual ~Base();
};

class DeriveA : public Base {
    int specialID;
public:
    DeriveA(int s, int i) : Base(i), specialID(s) {};
    ~DeriveA();
};

class DeriveB : public Base {
    int specialID;
public:
    DeriveB(int s, int i) : Base(i), specialID(s) {};
    ~DeriveB();
};

我的主要内容是这样的:

int main() {

    Base **Array;
    int i, n;
    Array = new Base*[5];
    for (i = 0 ; i < 5 ; i++) {
        n = rand() % 2;
        if (n)
            Array[i] = new DeriveA(i, n);
        else
            Array[i] = new DeriveB(i, n);
    }
}

如果遇到特定情况,我想将数组对象硬拷贝到其他对象上。我发现很难为它创建一个复制构造函数,因为Array[0] = Array[2]; 对我不起作用。我不想使用任何向量或 std::copy 因为那不是我的“教育”目标。

PS 1:赋值运算符是否更适合此目的,因为我已经初始化了数组的所有对象。

PS 2:由于它是通用代码,因此我遗漏了一些错误。请忽略它们并专注于问题。

【问题讨论】:

  • 我相信从更容易理解和更容易应用于更具体代码的角度来看,更通用的代码更有帮助。
  • Array[0] = Array[2]; 应该可以编译,但可能存在内存泄漏。
  • 你实际上并没有向我们展示你是如何做到的。

标签: c++ arrays class pointers inheritance


【解决方案1】:

如果你想克隆对象,而不是复制指向同一个对象的指针,你可以使用虚拟克隆函数:

class Base {
public:
    virtual Base* clone() const = 0;
    virtual ~Base();  // Don't forget 'virtual' here
};

class DeriveA : public Base {
public:
    virtual Base* clone() const { return new DeriveA(*this); }
};

class DeriveB : public Base {
public:
    virtual Base* clone() const { return new DeriveB(*this); }
};


// ...

Array[0] = Array[2]->clone();

【讨论】:

  • 我想我试图在错误的地方找到解决方案。因为在我的实际代码中,Base 是一个抽象类,并且在这一行中出现错误 virtual Base* clone() const { return new Base(*this); } 明显地。如果我删除了纯虚函数,代码就可以工作,但是有什么方法可以操作这条线并保留纯虚函数?
  • @AlexF。也使克隆函数抽象化(见编辑)。
【解决方案2】:

首先,你应该已经分配了Base*的数组:

Array = new Base*[5];

这就是初始化元素指针的方式:

Array[i] = new DeriveA(i,n);

不是这样的:

// * added for further clarification, otherwise invalid and rejected at compilation
*Array[i] = DeriveA(i,n);

因为那是:

  1. 取消引用未初始化的指针(未定义的行为)
  2. object slicing

请注意,您的 Basemissing a virtual destructor

然后当然是解除分配...您可以了解如何操作here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 2018-05-26
    相关资源
    最近更新 更多