在为类定义复制构造函数时,是否必须显式定义默认构造函数?请说明原因。
例如:
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();
}
如果没有默认构造函数,这个程序似乎工作正常。请解释为什么会这样?我真的很困惑这个概念......
答案 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'.
希望这会有所帮助。