私はプログラミングの初心者です。私はコピーコンストラクタについて学んでいます。さまざまなソースから、クラスオブジェクトを「ディープコピー」して、新しいオブジェクトのポインタメンバーが新しいメモリ位置を指すようにするには、コピーコンストラクタが便利であることがわかります。コピーコンストラクタとダイナミックメモリ
私の質問では、空のコピーコンストラクタ(EmptyCatクラスの場合)と同じ結果が得られた場合、私の例のCopyCatクラスのようにコピーコンストラクタを定義する利点は何ですか?
私の2番目の質問は、なぜCatクラスとEmptyCatクラスが違うのですか?それらの唯一の違いは、EmptyCatに空のコピーコンストラクタを定義することです。しかし私がプログラムを実行すると、コピー後のEmptyCatで、ポインタ・メンバーが新しい場所を指しているのに対して、クラスCatではそれは浅いコピーとして機能することがわかります。私は、プログラムを実行する場合
#include "iostream"
class Cat
{
public:
void GetMem() { std::cout << itsAge << "\n"; }
private:
int * itsAge = new int;
};
class EmptyCat
{
public:
EmptyCat() {}
~EmptyCat() {}
EmptyCat(EmptyCat&obj) {}
void GetMem() { std::cout << itsAge << "\n"; }
private:
int * itsAge = new int;
};
class CopyCat
{
public:
CopyCat() {}
~CopyCat() {}
CopyCat(CopyCat&obj);
int GetAge() { return *itsAge; }
void GetMem() { std::cout << itsAge << "\n"; }
private:
int * itsAge = new int;
};
CopyCat::CopyCat(CopyCat & obj)
{
itsAge = new int;
*itsAge = obj.GetAge();
}
int main()
{
Cat Garfield;
Cat Kitty(Garfield);
std::cout << "Memory addresses for the objects' <itsAge> member:" << std::endl;
std::cout << "Garfield and Kitty (Class Cat):" << std::endl;
Garfield.GetMem();
Kitty.GetMem();
EmptyCat Meow;
EmptyCat Purr(Meow);
std::cout << std::endl << "Meow and Purr (Class EmptyCat):" << std::endl;
Meow.GetMem();
Purr.GetMem();
CopyCat Fluffy;
CopyCat Felix(Fluffy);
std::cout << std::endl << "Fluffy and Felix (Class CopyCat):" << std::endl;
Fluffy.GetMem();
Felix.GetMem();
system("pause");
return 0;
}
私はこれを取得:
Memory addresses for the objects' <itsAge> member:
Garfield and Kitty (Class Cat):
00BBDA60
00BBDA60
Meow and Purr (Class EmptyCat):
00BB46A0
00BB8280
Fluffy and Felix (Class CopyCat):
00BB82B0
00BBE8A0
Press any key to continue . . .
クラスのメモリがリークしているので、実際には何の例でもありません。 –
コピーコンストラクタの動作に焦点を絞って、できるだけシンプルにしたいと考えました – SVG
しかし、そうすることで、興味深いものがすべて失われています。あなたのデストラクタが割り当てを削除するならば、あなたはすぐに3つのルールとすべてのルールを発見します。 –