【问题标题】:Copy-constructor when using inheritence使用继承时的复制构造函数
【发布时间】:2015-03-27 14:44:15
【问题描述】:

我的学校作业有问题。我应该创建一个系统来跟踪体育赛事中的竞争者。我有一个基类竞争者和两个派生自 ProfessionalExerciser 的类。
然后我有一个包含Contender **contenders 的寄存器类。而且我必须为这个类创建一个复制构造函数,但我不知道该怎么做。

我想过这样的事情

Register::Register(const Register& original)
{
    this->kap = original.kap;
    this->currentAmount = original.currentAmount;
    for (int i = 0; i < this->currentAmount; i++)
    {
        if (Professional* pro = dynamic_cast<Professional*>(this->contenders[i]))
        {
            this->contenders[i] = new Professional(*original.contenders[i]);
        }
        if (Exerciser* pro = dynamic_cast<Exerciser*>(this->contenders[i]))
        {
            this->contenders[i] = new Exerciser(*original.contenders[i]);
        }
    }
    this->initiate(this->currentAmount);
}

【问题讨论】:

  • 那么您对这段代码有什么问题?您可能想查看virtual constructor idiom(尤其是虚拟副本)。
  • 但是Register 类需要知道所有可能的派生类。或许你可以给基类一个virtual Base* clone() const;成员函数,所有派生类都实现为Base* clone() const { return new Derived (*this); }
  • this-&gt;contenders 是什么类型?根据类型,您可能有未定义的行为。 (它应该是一个向量。)
  • 它告诉我“没有与参数列表参数类型匹配的构造函数 Professional::Professional 的实例是:(Contender)”。我们不应该在这个作业中使用向量,如果你愿意,我可以发布所有代码

标签: c++ inheritance copy-constructor deep-copy


【解决方案1】:

我了解contenders 是指向指针数组的指针。

存在三个问题:

  • 您需要初始化contenders
  • dynamic_cast&lt;&gt; 检查应该使用原始对象
  • ProfessionalExerciser 复制构造函数肯定分别定义为复制 ProfessionalExerciser 类型的对象,而不是 Contender

这里建议更正:

Register::Register(const Register& original)
{
    kap = original.kap;
    currentAmount = original.currentAmount;
    contenders = new Contender[currentAmount];  // was missing
    for (int i = 0; i < currentAmount; i++)
    {
        if (Professional* pro = dynamic_cast<Professional*>(original.contenders[i]))
        {
            contenders[i] = new Professional(*pro);  // use the pro instead of contender
        }
        if (Exerciser* exe = dynamic_cast<Exerciser*>(original.contenders[i]))  
        {
            contenders[i] = new Exerciser(*exe);  // use exe instead of contender
        }
    }
    initiate(currentAmount);
}

三个建议:

  • 您不需要使用this-&gt; 为所有对象变量添加前缀。仅在成员函数本身的局部变量有歧义的情况下。
  • 考虑使用vector 而不是指向数组的指针
  • cmets 中提出的克隆方法将是您的 dynamic_cast&lt;&gt; 检查的一个非常好的和强大的替代方法

【讨论】:

  • 类型检查肯定应该在源对象上,而不是(空)目标。
猜你喜欢
  • 2015-04-11
  • 2012-09-20
  • 2019-01-12
  • 2015-08-07
  • 2014-06-15
  • 1970-01-01
相关资源
最近更新 更多