构造函数实例1:
#include <iostream>
using namespace std;
class Test
{
int num;
public:
Test(int);
~Test();
Test(Test& t);
void print();
};
Test::Test(int n)
{
num = n;
cout << "Test(int) : " << n << endl;
}
/*
Test::Test(Test& t)
{
num = t.num;
cout << "Test(Test&) : " << t.num << endl;
}
*/
void Test::print()
{
cout << "num = " << num << endl;
}
Test::~Test()
{
cout << "Destorying " << num << endl;
}
int main()
{
Test t(0);
t = 4;
t.print();
t = Test(10);
t.print();
return 0;
}
/*
Test(int) : 0 // 建立对象t, NO.1
Test(int) : 4 // 建立隐藏对象, NO.2
Destorying 4 // 析构隐藏对象, NO.2
num = 4 // NO.3
Test(int) : 10 // 由强制类型转换建立数据为10的临时对象, No.4
Destorying 10 // 析构数据为10的临时对象, NO.4
num = 10 // NO.5
Destorying 10 // 析构t对象
*/
复制初始化构造函数:
格式: X::X(X&) -- 必须使用引用参数
说明:
1. 在其中可以直接访问参数对象的私有成员
2. 在使用该类的一个对象初始化该类的另一个对象时,调用这个函数
3. 建立对象调用普通带参的构造函数的几种方法:
1).Test t(5); // 调用普通带参的构造函数
2).Test t = 5; // 相当于 Test t(5);
3).Test t = Test(5); /* C++标准规定:1. 先创建临时对象Test(5);
2. 调t拷贝构造进行初始化对象t;
3. 析构临时对象Test(5) , 编译器优化后 = Test(5) 等价于 = 5 */
(
// Test::Test(string n); // 在VC中,非基本数据类型, 调用时创建临时对象,并调用拷贝构造
Test t2 = Test("123"); // 创建临时对象
)
另:
A a;
A b = a; // 调用拷贝构造函数, 相当于 A b(a);
4). Test array[3] = {Test(1), Test(2), Test(3)};
/* 直接调用 Test::Test(int n); 如果编译器没有优化,则创建临时对象,调用拷贝构造*/
5). Test array[3] = {1,2,3}; /* 直接调用 Test::Test(int n); */
4. 如果程序中没有定义复制初始化构造函数,C++编译器将自动生成
一个缺省的复制初始化构造函数: Test::Test(const Test&)
Test::Test(const Test& e)
{
num = e.num;
}
5. 在函数返回一个对象时,要调用复制初始化构造函数创建临时对象用于返回给被调用者.
Test refun()
{
cout << "Test refun() start ..." << endl;
Test t(23);
cout << "Test refun() end ..." << endl;
return t; // a).返回时调用复制构造函数创建临时对象temp用于返回给被调者; b). 调用析构函数析构上面对象t,
}
int main()
{
Test t(3);
refun().print(); // c). 此语句执行后调用析构函数析构返回时的临时对象temp
return 0;
}
6. 在调用函数时,以值传递的方式传递对象,需要调用复制初始化构造函数初始化形参,
在函数返回时,形参对象的生命周期结束,形参的析构函数将被调用
void fun(Test t)
{
cout << "fun(Test) start ..." << endl;
t.print();
cout << "fun(Test) end ..." << endl;
} // 2). 调用析构函数析构形参对象
int main()
{
Test t(3);
fun(t); // 1). 调用复制初始化构造函数初始化形参对象
return 0;
}
7. 在定义函数时,如果要传递对象,建议使用形参使用对象的引用,好处如下:
1). 不会调用复制初始化构造函数.
2). 在引用的生存期结束时不调用析构函数.
3). 比值传递的程序效率更高.
浅复制:
打个比方吧!就像一个朋友让你把一个程序通过网络发给他,而你大大咧咧地把快捷方式发给了他,有什么用处呢?
C++提供的默认复制构造函数是这样的:
String(const String& a)
{
str=a.str;
len=a.len;
}
深复制:
手工定义一个复制构造函数:
String::String(const String& a)
{
len=a.len;
str=new char(len+1);
strcpy(str,a.str);
}