拷贝构造函数:功能:使用一个已经存在的对象来初始化一个新的同一类型的对象
拷贝构造函数的声明:只有一个参数,并且
参数为该对象的引用
如果类中没有说明拷贝构造函数,则系统自动生成一个缺省复制构造函数,作为该类的公有成员。
拷贝函数的参数必须是对象引用。
在C++中,下面三种对象需要调用拷贝构造函数:
1) 一个
对象作为
函数参数,以
值传递的方式
传入函数体;
2) 一个
对象作为
函数返回值,以
值传递的方式从函数
返回;
3) 一个
对象用于给
另一个对象进行
初始化(常称为复制初始化);
1.当函数的
形参是
类的对象,调用函数时,进行形参与实参结合时使用,这时要在内存新建立一个
局部对象,并把
实参拷贝到新的对象中,理所当然也要调用拷贝构造函数。
2.当函数的
返回值是类的对象,函数执行完成返回调用者时使用。理由也是要建立一个临时对象中,再返回调用者。为什么不直接用要返回的局部对象呢?因为
局部对象在离开建立它的函数时就消亡了,不可能在返回调用函数后继续生存,所以处理这种情况时,编译系统会在调用函数的表达式中创建一个
无名临时对象,该临时对象在生存周期值在函数调用处的表达式中。
3.所谓return对象,实际上是调用拷贝构造函数把该对象的值拷入
临时对象,如果返回的是变量,处理过程类似,只是不用调用构造函数。
4.
拷贝构造函数的另一种调用:当对象直接作为
参数
传给函数时,函数将建立对象的
临时拷贝
,这个拷贝过程也将调用拷贝构造函数。
Test.h
- # ifndef _TEST_H_
- # define _TEST_H_
- class Test
- {
- public:
- Test();
- Test(int num);
- //拷贝函数的参数必须是对象引用
- Test(const Test& other);
- ~Test();
- Test& operator = (const Test& other);
- void Display();
- private:
- int num_;
- };
- # endif //_TEST
Test.cpp
- # include "Test.h"
- # include <iostream>
- using namespace std;
- Test::Test():num_(0)
- {
- cout << num_ << endl;
- }
- Test::Test(int num):num_(num)
- {
- cout << num_<<endl;
- }
- Test::~Test()
- {
- cout << "Destory " << num_ << endl;
- }
- Test::Test(const Test& other):num_(other.num_)
- {
- cout <<"Inilializing with other " << endl;
- }
- Test& Test::operator=(const Test& other)
- {
- cout << "Test::operator" << endl;
- if(this == &other)
- {
- return *this; //t = t; 直接返回
- }
- num_ = other.num_;
- return *this;//返回自身
- }
- void Test::Display()
- {
- cout << num_ << endl;
- }
main.cpp
- # include "Test.h"
- # include <iostream>
- using namespace std;
- int main(void)
- {
- Test t(10);//调用带一个参数的构造函数
- //t对象初始化t2对象,这时会调用拷贝构造函数
- Test t2 = t; //此时=不是赋值运算符,而是特殊的解释
- return 0;
- }
运行结果:
下面用实例讲解在什么情况下会调用拷贝构造函数,什么情况下不会调用拷贝构造函数
Test.h
- # ifndef _TEST_H_
- class Test
- {
- public:
- Test();
- Test(int num);
- //拷贝构造函数
- Test(const Test&);
- ~Test();
- Test& operator=(const Test& other);
- void Display();
- private:
- int num_;
- };
- # endif //_TEST_H_
Test.cpp
- #include "Test.h"
- # include <iostream>
- using namespace std;
- Test::Test(void):num_(0)
- {
- cout << num_ << endl;
- }
- Test::Test(int num):num_(num)
- {
- cout << num_<<endl;
- }
- Test::~Test(void)
- {
- cout << "Deatory ..." << endl;
- }
- Test::Test(const Test& other):num_(other.num_)
- {
- cout << "Iniliazing with other..." << endl;
- }
- Test& Test::operator=(const Test& other)
- {
- cout << "Test::operator "<< endl;
- if(this == &other)
- {
- return *this;
- }
- num_ = other.num_;
- return *this;
- }
- void Test::Display()
- {
- cout << num_ << endl;
- }
main.cpp
- # include "Test.h"
- # include <iostream>
- using namespace std;
- void TestFun(const Test t)
- {
- }
- //因为是引用不会构造对象分配内存的
- void TestFun_reference_parameter(const Test& t)
- {
- }
- const Test& TestFun_const_return_reference (const Test& t)
- {
- return t;
- }
- //返回对象的时候,要创建一个临时对象
- Test TestFun_return_object(const Test& t)
- {//进行复制操作
- return t;//临时对象
- }
- int main(void)
- {
- Test t(10);//调用拷贝构造函数
- cout << "." << endl;
- TestFun(t);//调用拷贝构造函数
- cout << ".." << endl;
- 因为是引用不会构造对象分配内存的
- TestFun_reference_parameter(t);
- Test t2 = t;//调用拷贝构造函数
- cout << "..." << endl;
- TestFun_return_object(t); //调用拷贝构造函数
- t = TestFun_return_object(t);//引用的话,临时对象也不会马上被销毁
- cout << "...." << endl;
- //TestFun(t);
- Test t4 = TestFun_const_return_reference(t);//调用拷贝构造函数 ,因为返回的是t
- return 0;
- }
运行结果: