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

时间:2009-10-18 18:49:33

标签: c++ constructor copy

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

例如:

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;
}

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

#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 个答案:

答案 0 :(得分:33)

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

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

例如:

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

S dummy(0);

S::S(const S& = dummy) {
}

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

答案 1 :(得分:3)

您不必同时定义它们。但是,一旦为类定义了任何构造函数,所有默认构造函数都将变为不可用。所以 - 如果你想复制构造和构造而不复制,你需要定义一个非默认(即显式)默认(即没有参数)构造函数。

如果定义了复制构造函数,通常也应该覆盖赋值运算符。

答案 2 :(得分:1)

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

这并不总是一个问题。

如果你不希望你的类是默认构造的,那么完全没有声明默认的构造函数。但是,如果您希望它是默认构造的(例如,如果您想取消注释示例中的X x1;行),那么您必须声明并定义默认构造函数。

另请注意,默认构造函数是可以不带参数调用的任何构造函数,而不仅仅是没有参数的构造函数。 X::X(int = 5)是一个非常好的默认构造函数。

答案 3 :(得分:0)

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'.

希望这会有所帮助。