C++ 理解复制构造函数的工作原理

C++ 理解复制构造函数的工作原理,c++,copy-constructor,C++,Copy Constructor,为了理解构造函数、复制构造函数、析构函数的工作原理,我编写了以下代码 #include <iostream> using namespace std; class Cat { public: Cat(); Cat(Cat&); ~Cat(); int itsage; }; Cat::Cat() { cout << "Constructor called\n"; cout << this <&l

为了理解构造函数、复制构造函数、析构函数的工作原理,我编写了以下代码

#include <iostream>
 using namespace std; 
 class Cat
{
 public:
  Cat();
  Cat(Cat&);
  ~Cat();
  int itsage;
};
 
 Cat::Cat()
{
 cout << "Constructor called\n";
 cout << this << endl;
 itsage=2;
}
 
 Cat::Cat(Cat& theCat)
{
 cout << "Copy constructor called\n";
 cout << this << endl;
 itsage=theCat.itsage;
}

 Cat::~Cat()
{
 cout << "Destructor called\n";
 cout << this << endl;
}
 
 Cat myFunction(Cat Frisky)
{
 cout << "Inside myFunction\n";
 cout << "Frisky's address : " << &Frisky ; 
 cout << "\nFrisky's age: " << Frisky.itsage << "\n";
 Frisky.itsage=100;
 cout << "Reassigned Frisky's age: "<< Frisky.itsage << "\n";
 return Frisky;
}
 
 int main()
{
 Cat Mani;
 cout << "Mani's address : " << &Mani ;
 cout << "\nMani's age: " << Mani.itsage << "\n";
 myFunction(Mani);
 return 0;
}

除了在第二次调用复制构造函数时存储在地址
0x61ff08
处的内容之外,我觉得一切都正常?这意味着我们可以看到存储在地址
0x61ff0c
0x61ff04
中的内容,它们只不过是
Frisky
Mani
。那么,在
0x61ff08
上看不见的东西是什么

我想通过在
main
函数中做一点小小的更改,使该对象可见

#include <iostream>
 using namespace std; 
 class Cat
{
 public:
  Cat();
  Cat(Cat&);
  ~Cat();
  int itsage;
};
 
 Cat::Cat()
{
 cout << "Constructor called\n";
 cout << this << endl;
 itsage=2;
}
 
 Cat::Cat(Cat& theCat)
{
 cout << "Copy constructor called\n";
 cout << this << endl;
 itsage=theCat.itsage;
}

 Cat::~Cat()
{
 cout << "Destructor called\n";
 cout << this << endl;
}
 
 Cat myFunction(Cat Frisky)
{
 cout << "Inside myFunction\n";
 cout << "Frisky's address : " << &Frisky ; 
 cout << "\nFrisky's age: " << Frisky.itsage << "\n";
 Frisky.itsage=100;
 cout << "Reassigned Frisky's age: "<< Frisky.itsage << "\n";
 return Frisky;
}
 
 int main()
{
 Cat Mani;
 cout << "Mani's address : " << &Mani ;
 cout << "\nMani's age: " << Mani.itsage << "\n";
 Cat Sweety = myFunction(Mani); 
 cout << "Sweety's age : " << Sweety.itsage ;
 return 0;
}


我真的不知道出了什么问题。

您的第一个代码返回了
Frisky
的副本,该副本来自
myFunction
,这就是附加副本的来源

第二个代码不起作用,因为复制构造函数错误地接受了非常量引用,并且无法将从
myFunction
返回的临时值传递给非常量引用


与您的问题没有直接关系,但您也应该遵守并实现赋值运算符。

您的第一个代码从
myFunction
返回一份
Frisky
,这就是附加副本的来源

Cat(Cat &);
第二个代码不起作用,因为复制构造函数错误地接受了非常量引用,并且无法将从
myFunction
返回的临时值传递给非常量引用

与您的问题不直接相关,但您也应遵守并执行赋值运算符

Cat(Cat &);
在此处使用
const

Cat(const Cat &);

不相关,但考虑像这样使用初始化。

Cat Sweety{myFunction(Mani)};
在此处使用
const

Cat(const Cat &);

不相关,但考虑像这样使用初始化。

Cat Sweety{myFunction(Mani)};

有点奇怪。。当我们通过
Mani
时,复制构造函数是可以的,但当我们返回
Frisky
时,它出现了问题。。为什么?Mani不是临时的,所以可以绑定到非常量引用Hanks。。最后一件事。。听起来可能很难看,但我有一段时间一直在怀疑这个问题。。Frisky的副本存储在
0x61ff08
中,之后它也被销毁。。那么
Mani
(这是我们调用
myFunction
时创建的)的什么abt副本呢。。它不是存储在某个地方还是被销毁了吗?Mani的副本很活泼,它存储在
myFunction
的堆栈中,并在function的末尾被销毁,这有点奇怪。。当我们通过
Mani
时,复制构造函数是可以的,但当我们返回
Frisky
时,它出现了问题。。为什么?Mani不是临时的,所以可以绑定到非常量引用Hanks。。最后一件事。。听起来可能很难看,但我有一段时间一直在怀疑这个问题。。Frisky的副本存储在
0x61ff08
中,之后它也被销毁。。那么
Mani
(这是我们调用
myFunction
时创建的)的什么abt副本呢。。它不是存储在某个地方还是被销毁了吗?Mani的副本很活泼,它存储在
myFunction
的堆栈中,并在函数结束时被销毁