您的位置:首页 > 编程语言 > C语言/C++

C++拷贝构造函数的学习(一)

2013-04-10 12:59 295 查看
拷贝构造函数:功能:使用一个已经存在的对象来初始化一个新的同一类型的对象

拷贝构造函数的声明:只有一个参数,并且参数为该对象的引用
如果类中没有说明拷贝构造函数,则系统自动生成一个缺省复制构造函数,作为该类的公有成员。
拷贝函数的参数必须是对象引用。

在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;
}

运行结果:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息