代码之家  ›  专栏  ›  技术社区  ›  Light_handle

复制构造函数和默认构造函数

  •  14
  • Light_handle  · 技术社区  · 16 年前

    在为类定义复制构造函数时,是否必须显式定义默认构造函数??请说明原因。

    如:

    class A 
    {
        int i;
    
        public:
               A(A& a)
               {
                   i = a.i; //Ok this is corrected....
               }
    
               A() { } //Is this required if we write the above copy constructor??
    };      
    

    另外,如果我们为一个类(而不是复制构造函数)定义了任何其他参数化的构造函数,我们还必须定义默认的构造函数吗??考虑不带复制构造函数的上述代码,并将其替换为

    A(int z)
    {
        z.i = 10;
    }
    

    在看到答案后,我写了下面的程序。

    #include <iostream>
    
    using namespace std;
    
    class X
    {
        int i;
    
        public:
                //X();
                X(int ii);
                void print();
    };
    
    //X::X() { }
    
    X::X(int ii)
    {
        i = ii;
    }
    
    
    void X::print()
    {
        cout<<"i = "<<i<<endl;
    }
    
    int main(void)
    {
        X x(10);
      //X x1;
        x.print();
      //x1.print();
    }
    

    如果没有默认的构造函数,这个程序似乎可以正常工作。请解释一下为什么会这样??我真的对这个概念感到困惑……

    4 回复  |  直到 11 年前
        1
  •  33
  •   AnT stands with Russia    16 年前

    对。一旦你明确声明 绝对任何 类的构造函数,编译器停止提供隐式默认构造函数。如果仍然需要默认的构造函数,则必须自己显式声明和定义它。

    P.S.可以编写一个复制构造函数(或转换构造函数,或任何其他构造函数),也可以 违约 构造函数。如果您的新构造函数属于该类别,则不再需要提供其他默认构造函数:)

    例如:

    // Just a sketch of one possible technique    
    struct S {
      S(const S&);
      S(int) {}
    };
    
    S dummy(0);
    
    S::S(const S& = dummy) {
    }
    

    在上面的示例中,复制构造函数同时是默认的构造函数。

        2
  •  3
  •   Steve314    16 年前

    你不必定义两者。但是,一旦为一个类定义了任何构造函数,所有默认的构造函数都将不可用。因此-如果您希望既复制构造又不复制构造,则还需要定义一个非默认(即显式)默认(即无参数)构造函数。

    如果定义了一个复制构造函数,通常也应该重写赋值运算符。

        3
  •  1
  •   coppro    16 年前

    正如Andreyt所说,如果显式声明任何构造函数,包括复制构造函数,编译器将不会隐式声明或定义默认构造函数。

    这并不总是个问题。

    如果不希望类是默认可构造的,那么最好不要声明默认构造函数。但如果希望它是默认可构造的(例如,如果要取消对 X x1; 行),然后必须声明和定义默认构造函数。

    还要注意,默认的构造函数是任何可以不带参数调用的构造函数,而不仅仅是一个不带参数的构造函数。 X::X(int = 5) 是一个完美的默认构造函数。

        4
  •  0
  •   Whoami    13 年前

    1)没有参数的构造函数称为“默认构造函数”。 2)如果用户没有提供以下任何构造函数,则编译器声明 您的默认构造函数。

      2a) Copy Constructor
      2b) Non-default constructor
      2C) default constructor. 
    

    3)如果编译器声明了“默认构造函数”,则称为“隐式声明的默认构造函数”,

    4)“隐式声明的默认构造函数”有两种类型

       4a) **trivial** Constructor
       4b) **non-trivial** Constructor. 
    

    5)当存在 5a)无参考变量 5b)无虚拟功能 5C)没有虚拟基类。 5d)父类具有“平凡”构造函数,

    Else, it is said to be 'non-trivial'.
    

    希望这有帮助。