返回值为对象调用拷贝构造函数

转载 2015年07月06日 21:35:29


copyFrisky对象超出作用区域,
这时会调用复制构造函数创建该copyFrisky对象的一个临时拷贝对象,
并把它赋给主调函数中需要的对象,此时是成员复制;第二个例子可以证明!
然后调用该临时拷贝对象的析构函数释放这个对象占用的内存资源,
接着再调用形参对象的析构函数释放形参对象占用的内存资源!

以下是一个验证的例子:

//------------------------------------
//file name: testPlace.cpp
//purpose: to test copy constructor
//------------------------------------
#include <iostream.h>

class Cat
{
public:
Cat(); //default constructor
Cat(const Cat &);        //copy constructor
~Cat();           //destructor
int GetAge() const {return itsAge;}
int GetWeight() const {return itsWeight;}
void SetAge(int age) {itsAge=age;}
void SetWeight(int weight) {itsWeight=weight;}
private:
int itsAge;
int itsWeight;
};

Cat::Cat()          //constructor realization
{
itsAge=1;
itsWeight=10;
cout<<"constructor\n";
}

Cat::Cat(const Cat & theCat)     //copy constructor realization
{
itsAge=theCat.GetAge();
itsWeight=theCat.GetWeight();
cout<<"copy constructor\n";
}

Cat::~Cat()          //destructor realization
{
itsAge=0;
itsWeight=0;
cout<<"destructor\n";
}

Cat DisplayCopyFrisky(Cat);     //subfuction header

int main()          //main function
{
Cat Frisky,copyFrisky;
cout<<"Frisky's age: "<<Frisky.GetAge() <<endl;
Frisky.SetAge(2);
copyFrisky=DisplayCopyFrisky(Frisky);     //call subfuction
cout<<"copyFrisky's age: "<<copyFrisky.GetAge() <<endl;
Frisky.SetAge(3);
cout<<"Frisky's age: "<<Frisky.GetAge() <<endl;
return 0;
}

Cat DisplayCopyFrisky(Cat copyFrisky) //subfuction realization
{
cout<<"copyFrisky' age: "<<copyFrisky.GetAge() <<endl;
cout<<"copyFrisky' weight: "<<copyFrisky.GetWeight() <<endl;
copyFrisky.SetAge(4);
cout<<"copyFrisky's age: "<<copyFrisky.GetAge() <<endl;
return copyFrisky;
}

证明返回对象的值时是成员复制的第二个例子:由于返回对象值时采用的是浅复制,而对象中含有指向自由存储区的指针变量,从而导致临时拷贝对象中的指针变量和接受返回值的对象(在此设为:copyFrisky)的指针变量同时指向同一内存块,而当浅复制完毕后,析构函数释放临时拷贝对象的内存资源,导致接受返回值的对象copyFrisky中的指针变量变成迷途指针,返回到主程序之后,在主程序结束前,应该先把copyFrisky中的迷途指针设为空指针或者指向某一分配的内存,否则当主程序结束调用析构函数释放copyFrisky对象的资源时,将会导致错误!正如第二个例子所示!改正后的程序如第三个例子!

//------------------------------------
//file name: testPlace.cpp
//purpose: to test copy constructor
//------------------------------------
#include <iostream.h>
class Cat
{
public:
Cat();           //default constructor
Cat(const Cat &);        //copy constructor
~Cat();           //destructor
int GetAge() const {return *itsAge;}
int GetWeight() const {return *itsWeight;}
int* GetItsAgeValue() const {return itsAge;}
int* GetItsWeightValue() const {return itsWeight;}
void DeleteAge() {delete itsAge;itsAge=0;}
void DeleteWeight() {delete itsWeight;itsWeight=0;}
void SetAge(int age) {*itsAge=age;}
void SetWeight(int weight) {*itsWeight=weight;}
private:
int *itsAge;
int *itsWeight;
};

Cat::Cat()          //constructor realization
{
itsAge=new int;
itsWeight=new int;
*itsAge=1;
*itsWeight=10;
cout<<"constructor\n";
}

Cat::Cat(const Cat & theCat)     //copy constructor realization
{
itsAge=new int;
itsWeight=new int;
*itsAge=theCat.GetAge();
*itsWeight=theCat.GetWeight();
cout<<"copy constructor\n";
}

Cat::~Cat()          //destructor realization
{
delete itsAge;
itsAge=0;
delete itsWeight;
itsWeight=0;
cout<<"destructor\n";
}

Cat DisplayCopyFrisky(Cat);     //subfuction header

int main()          //main function
{
Cat Frisky,copyFrisky;
cout<<"Frisky's age: "<<Frisky.GetAge() <<endl;
Frisky.SetAge(2);

copyFrisky.DeleteAge();
copyFrisky.DeleteWeight();

copyFrisky=DisplayCopyFrisky(Frisky);     //call subfuction
cout<<"copyFrisky's age: "<<copyFrisky.GetItsAgeValue() <<endl;
cout<<"copyFrisky's weight: "<<copyFrisky.GetItsWeightValue() <<endl;

cout<<"copyFrisky's age: "<<copyFrisky.GetAge() <<endl;   //lost pointer
cout<<"copyFrisky's weight: "<<copyFrisky.GetWeight() <<endl; //lost pointer

Frisky.SetAge(3);
cout<<"Frisky's age: "<<Frisky.GetAge() <<endl;
return 0;
}

Cat DisplayCopyFrisky(Cat copyFrisky)   //subfuction realization
{
cout<<"copyFrisky's age: "<<copyFrisky.GetItsAgeValue() <<endl;
cout<<"copyFrisky's weight: "<<copyFrisky.GetItsWeightValue() <<endl;
copyFrisky.SetAge(4);
cout<<"copyFrisky's age: "<<copyFrisky.GetAge() <<endl;
return copyFrisky;
}

第三个例子:这个例子返回的是迷途指针,此目的只是想了解返回对象值时的一些情况!

//------------------------------------
//file name: testPlace.cpp
//purpose: to test copy constructor
//------------------------------------
#include <iostream.h>
class Cat
{
public:
Cat();           //default constructor
Cat(const Cat &);        //copy constructor
~Cat();           //destructor
int GetAge() const {return *itsAge;}
int GetWeight() const {return *itsWeight;}
int* GetItsAgeValue() const {return itsAge;}
int* GetItsWeightValue() const {return itsWeight;}
void DeleteAge() {delete itsAge;itsAge=0;}
void DeleteWeight() {delete itsWeight;itsWeight=0;}
void SetAgeEmpty() {itsAge=0;}
void SetWeightEmpty() {itsWeight=0;}
void SetAge(int age) {*itsAge=age;}
void SetWeight(int weight) {*itsWeight=weight;}
private:
int *itsAge;
int *itsWeight;
};

Cat::Cat()          //constructor realization
{
itsAge=new int;
itsWeight=new int;
*itsAge=1;
*itsWeight=10;
cout<<"constructor\n";
}

Cat::Cat(const Cat & theCat)     //copy constructor realization
{
itsAge=new int;
itsWeight=new int;
*itsAge=theCat.GetAge();
*itsWeight=theCat.GetWeight();
cout<<"copy constructor\n";
}

Cat::~Cat()          //destructor realization
{
delete itsAge;
itsAge=0;
delete itsWeight;
itsWeight=0;
cout<<"destructor\n";
}

Cat DisplayCopyFrisky(Cat);     //subfuction header

int main()          //main function
{
Cat Frisky,copyFrisky;
cout<<"Frisky's age: "<<Frisky.GetAge() <<endl;
Frisky.SetAge(2);

copyFrisky.DeleteAge();
copyFrisky.DeleteWeight();
copyFrisky=DisplayCopyFrisky(Frisky);     //call subfuction

copyFrisky.SetAgeEmpty();
copyFrisky.SetWeightEmpty();

cout<<"copyFrisky's age: "<<copyFrisky.GetItsAgeValue() <<endl;
cout<<"copyFrisky's weight: "<<copyFrisky.GetItsWeightValue() <<endl;

//cout<<"copyFrisky's age: "<<copyFrisky.GetAge() <<endl;   //lost pointer
//cout<<"copyFrisky's weight: "<<copyFrisky.GetWeight() <<endl; //lost pointer

Frisky.SetAge(3);
cout<<"Frisky's age: "<<Frisky.GetAge() <<endl;
return 0;
}

Cat DisplayCopyFrisky(Cat copyFrisky)   //subfuction realization
{
cout<<"copyFrisky's age: "<<copyFrisky.GetItsAgeValue() <<endl;
cout<<"copyFrisky's weight: "<<copyFrisky.GetItsWeightValue() <<endl;
copyFrisky.SetAge(4);
cout<<"copyFrisky's age: "<<copyFrisky.GetAge() <<endl;
return copyFrisky;
}

C++中拷贝构造函数的调用与C++返回值优化

C++ 拷贝构造函数 深拷贝 浅拷贝

拷贝构造函数 参数传递 返回值

拷贝构造函数的调用通常发生在以下两种情况

C++函数参数,返回值,拷贝构造函数等

相信大家对C++的特性有了比较多的了解, 这一节我们来对函数参数(实参, 虚参), 返回值机制;类深度拷贝构造,赋值操作符 使用更深一步的了解。如果你对这一节完全了解,恭喜你,你对C++的了解不...

拷贝构造函数在哪些地方用,函数参数,函数返回值

首先看个程序。 #include using namespace std; class A { public: A() { cout
  • bxyill
  • bxyill
  • 2013年05月24日 23:35
  • 2448

关于C++中在函数中按值返回、临时对象、拷贝构造函数的一点理解

几乎所有C++的书籍中都强烈建议函数返回的时候,要使用按引用返回、甚至直接返回指针,尤其是涉及到class和struct的时候。 如果函数返回对象,而不是指针,那么在执行return的时候,...
  • lslxdx
  • lslxdx
  • 2012年04月18日 20:48
  • 1293

c++怎样让返回对象的函数不调用拷贝构造函数

我们知道拷贝构造函数有两种“默默”的方式被调用 1. 想函数传入 值参数 2. 函数返回 值类型 今天我们讨论函数返回值类型的情况。 得到结论是 1. 当对象有拷贝构造函数(系统为我们生成、或者我们自...

C++构造函数、拷贝构造函数、赋值运算符漫谈(二)——函数返回值

首先我们先看一下C程序的返回值处理情况,我们知道当C函数返回int等小型数据时直接将返回值放入eax寄存器。那当返回大的数据结构又是如何处理呢?看如下一段代码: #include typede...

C++对象的拷贝构造函数 赋值函数 调用情况

来源: http://www.tnove.com/?p=66     最近从新做c++,关于类的拷贝构造函数和赋值操作有点疑问,于是查询了下资料,网上也搜了下,线面总结下我的理解。先应用...

对象作为函数参数时调用拷贝构造函数、引用做函数参数时只是传递地址

对象也可以作为函数的参数传递给函数,其转递方法与传递其他类型的数据一样,可采用值传递和地址传递两种方法。 值传递:是把对象的拷贝而不是本身传递给函数,函数中对参数对象的任何修改都不会影响调用该函...

C++拷贝构造函数和赋值操作

  • 2012年01月10日 13:51
  • 3KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:返回值为对象调用拷贝构造函数
举报原因:
原因补充:

(最多只允许输入30个字)