【问题标题】:Object oriented programming , inheritance , copy constructors面向 对象 编程 , 继承 , 复制 构造
【发布时间】:2011-01-06 03:35:18
【问题描述】:

假设我有一个基类Person,并且我从基类Person 公开继承了一个类Teacher。 现在在主函数中我写了这样的东西

// name will be passed to the base class constructor and 17
// is for derived class constructor.
Teacher object(“name”,17) ;
Teacher object1=object; //call to copy constructor

现在我还没有为这两个类编写复制构造函数,当然会调用默认的复制构造函数。 Person 类的默认复制构造函数将首先调用基类的复制构造函数。

现在的问题是假设我只为基类编写复制构造函数,发生的情况是,派生类的默认复制构造函数将调用我编写的复制构造函数。
现在假设我为这两个类编写了复制构造函数。现在派生类(即教师)的复制构造函数将调用基类的默认构造函数而不是复制构造函数,为什么?
只有派生类的默认拷贝构造函数才能自动调用基类的拷贝构造函数吗?

【问题讨论】:

  • 没有“默认复制构造函数”之类的东西。但是是的,编译器生成的复制构造函数会调用基类的复制构造函数。
  • 谢谢你,我明白了。

标签: c++ oop


【解决方案1】:
class Base {
    int num_
public:
    Base(int n) : num_(n) { }
    // copy constructor defined by compiler
};

class Derived : public Base {
    float flt_;
public:
    Derived(float f, int n) : Base(n), flt_(f) { }
    // Copy constructor
    Derived(const Derived& other)
        : Base(other) // OK to explicitly call compiler generated copy constructor
        , flt_(other.flt_)
    {
    }
};

【讨论】:

    【解决方案2】:

    您必须显式调用基本副本构造函数:

    Teacher(const Teacher& other) 
        : Person(other) // <--- call Person's copy constructor.
        , num_(other.num_)
    {
    }
    

    否则会调用Person的默认构造函数。


    我似乎没有完全理解这个问题,所以我只会说我认为相关的所有内容,希望这会对 OP 有所帮助。

    默认情况下,所有用户定义的构造函数都会调用其基类的默认构造函数(除非它们显式调用不同的构造函数),基类的默认构造函数是用户定义的还是编译器生成的都没有关系。

    当编译器生成复制构造函数时,它会调用基类的复制构造函数。

    编译器定义的构造函数并不特殊,可以显式调用:

    class Base {
        int num_
    public:
        Base(int n) : num_(n) { }
        // copy constructor defined by compiler
    };
    
    class Derived : public Base {
        float flt_;
    public:
        Derived(float f, int n) : Base(n), flt_(f) { }
        // Copy constructor
        Derived(const Derived& other)
            : Base(other) // OK to explicitly call compiler generated copy constructor
            , flt_(other.flt_)
        {
        }
    };
    

    更多详情请看Wikipedia article

    【讨论】:

    • 是的,我知道,我必须明确地调用它,但这不是我的问题,我的问题是“只有派生类的默认复制构造函数可以调用基类的复制构造函数(默认或用户写的)”?
    • 我不明白你的问题。
    • 只有派生类的默认拷贝构造函数可以自动调用基类的拷贝构造函数,基类的拷贝构造函数是默认拷贝构造函数还是用户编写的拷贝构造函数???有意义吗?
    • 编译器生成版本的拷贝构造函数并不特殊。编译器生成的复制构造函数将调用基类的复制构造函数(不管它是用户编写的还是编译器生成的)然后它将调用每个成员的复制构造函数(不管它们是用户编写的还是编译器生成的副本构造函数)。
    • 注意:没有“默认复制构造函数”之类的东西。您似乎混淆了术语“默认构造函数”,它是在没有提供参数时调用的构造函数。有编译器生成的方法“复制构造函数”“赋值运算符”“默认构造函数”“析构函数”
    【解决方案3】:

    如果您不指定复制构造函数,编译器会自动生成一个。该构造函数的生成方式是调用基类的复制构造函数。

    如果您自己实现复制构造函数,您还可以指定应该使用哪个基类构造函数(参见 Motti 的回答)。如果不指定任何内容,则使用默认构造函数(这就是它被称为“默认构造函数”的原因:在没有显式指定构造函数时使用)。

    所以编译器会自动生成一个合理的复制构造函数,但是如果你想要一些特别的东西,就没有更多的魔法了,你必须自己指定构造函数应该是什么样子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 2015-04-11
      相关资源
      最近更新 更多