注意, 如果不主动编写拷贝构造函数和赋值函数,编译器将以位拷贝的方式自动生成这两个缺省的函数。
-- 定义
class CC
{
public:
CC(const CC& cc) { cout << "in CC(cont CC&)" << endl; } // 拷贝构造函数
CC& operator= (const CC&) { cout << "in CC& operator= (const CC&)" << endl; return *this; } //赋值
public:
...
};
-- 什么时候使用拷贝构造函数, 什么情况下使用赋值
当对象不存在的时候用 - 拷贝构造函数
CC c1;
CC c2 = c1; //调用拷贝构造函数
当对象已经存在的时候 - 赋值
CC c1;
CC c2;
c1 = c2; //赋值
-- 注意
1. 缺省拷贝构造函数会主动去调用父类和成员变量的拷贝构造函数; 而如果用户重定义了拷贝构造函数, 那么会执行基类和成员变量的缺省构造函数, 而不是拷贝构造函数, 举个例子来说
---- 使用缺省构造函数
class A {
public:
A() { cout << "in A()" << endl; }
A(const A& a) { cout << "in A(cont A&)" << endl; }
};
class B {
public:
B() { cout << "in B()" << endl; }
B(const B& b) { cout << "in B(cont B&)" << endl; }
B(int i) { cout << "in B(int i)" << endl; }
};
class C {
public:
C() { cout << "in C()" << endl; }
C(const C& c) { cout << "in C(cont C&)" << endl; }
};
class CC: public C {
public:
CC(int i):id(i),b(10) { cout << "in CC()" << endl; }
//CC(const CC& cc) { cout << "in CC(cont CC&)" << endl; }
public:
A a;
B b;
private:
int id;
};
int main ()
{
CC c1(1);
CC c3 = c1;
return 0;
}
# CC t.C && ./a.out
in C() // c1: 父类 构造函数
in A() // c1: 成员a 构造函数
in B(int i) // c1: 成员b 构造函数
in CC() // c1: 类本身 构造函数
in C(cont C&) // c3: 父类 拷贝构造函数
in A(cont A&) // c3: 成员a 拷贝构造函数
in B(cont B&) // c3: 成员b 拷贝构造函数
!!!??????这里我有一个问题, 很多参考书上说缺省的拷贝构造函数使用的是"位拷贝"的方式, 那么既然是"位拷贝", 他可以把整个成员(sizeof(CC))拷贝过来, 即包括父类的空间和成员变量的空间, 那为什么还要调用父类和成员的拷贝构造函数呢?难道他的"位拷贝"操作只拷贝属于当前类的原始类型(int, char, etc)数据的空间。
答案应该是那样的, 下面程序表明
class A {
public:
A() :ma(0) { cout << "in A()" << endl; }
A(int i) :ma(i) { cout << "in A(int i)" << endl; }
A(const A& a) { cout << "in A(cont A&)" << endl; ma=2; }
public:
int ma;
};
class CC {
public:
CC(int i):a(1) { cout << "in CC()" << endl; }
public:
A a;
};
int main ()
{
CC c1(1);
cout << c1.a.ma << endl;
CC c3 = c1;
cout << c3.a.ma << endl;
return 0;
}
得到的结果是
# CC t.C && ./a.out
1
2
说明, 虽然c1中ma的值是1, 但是c3使用的是拷贝构造函数, 缺省的"位拷贝"构造函数会调用成员A的拷贝构造函数, 而在A的拷贝构造函数中他重写了ma的值, 所以我们打印出在c3中ma的值是2, 而不是1(如果按整个CC"位拷贝" 即sizeof(CC)那么应该得到1).
!!!end of
---- 使用自定义构造函数
class A {
public:
A() { cout << "in A()" << endl; }
A(const A& a) { cout << "in A(cont A&)" << endl; }
};
class B {
public:
B() { cout << "in B()" << endl; }
B(const B& b) { cout << "in B(cont B&)" << endl; }
B(int i) { cout << "in B(int i)" << endl; }
};
class C {
public:
C() { cout << "in C()" << endl; }
C(const C& c) { cout << "in C(cont C&)" << endl; }
};
class CC: public C {
public:
CC(int i):id(i),b(10) { cout << "in CC()" << endl; }
//CC(const CC& cc) { cout << "in CC(cont CC&)" << endl; }
public:
A a;
B b;
private:
int id;
};
int main ()
{
CC c1(1);
CC c3 = c1;
return 0;
}
输出结果如果
# CC t.C && ./a.out
in C() // c1: 父类 构造函数
in A() // c1: 成员a 构造函数
in B(int i) // c1: 成员b 构造函数
in CC() // c1: 类本身 构造函数
in C() // c3: 父类 缺省构造函数
in A() // c3: 成员a 构造函数
in B() // c3: 成员b 构造函数
in CC(cont CC&) // c3: 类本身 拷贝 构造函数