1.默认构造
class A
{
public:
A() {}; //default构造函数
};
class B
{
public:
B(int _x = 0) : x(_x) {} //default构造函数
private:
int x;
};
class C
{
public:
C(int _x) : x(_x) {} //不是default构造函数
private:
int x;
};
int main()
{
A a;
B b;
C c;//error:no matching function for call to 'C::C()'
return 0;
}
2.explicit
将构造函数声明为explicit,可以阻止他们被用来执行隐式类型转换(implicit type conversions),但他们仍可被用来执行显示类型转换(explicit type conversions)。explicit类型的构造函数能禁止编译器执行非预期的类型转换,应尽量使用explicit代替non-explicit。
class D
{
public:
explicit D(int _x = 0) : x(_x) {} //default构造函数
private:
int x;
};
void func(D obj)
{
//do something...
}
int main()
{
D d;
func(d);
func(123);//error: could not convert '123' from 'int' to 'D'
func(D(123));//ok
return 0;
}
3.copy构造函数
class E
{
public:
E(int _x = 0) : x(_x) {} //default构造函数
E(const E& rhs) //copy构造函数
{ x = rhs.x; }
E& operator=(const E& rhs) //copy assignment操作符
{
x = rhs.x;
return *this;
}
private:
int x;
};
int main()
{
E e1; //调用default构造函数
E e2(e1); //调用copy构造函数
e1 = e2; //调用copy assignment操作符
E e3 = e2; //调用copy构造函数
return 0;
}
copy构造和copy赋值区分:如果有一个新对象被定义(如上文e3),一定会有一个构造函数被调用,不可能调用赋值操作。若没有新对象被定义(如上文e1 = e2句),就不会调用构造函数,而是赋值操作符“=”被调用了。
,
copy构造函数定义了一个对象如何
passed-by-value(传值)。passed-by-value以为只调用了copy构造函数,代价较大,以pass-by-reference-to-const代替往往是比较好的选择。