質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

551閲覧

コピーコンストラクタについて

user012

総合スコア11

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/12/18 11:57

コピー代入演算子の中でdelete mFoo; としている理由を教えてください。

c++

1#include <iostream> 2 3class Foo 4{ 5 int mData; 6public: 7 Foo(int iData) : mData(iData) { } 8 int get() { return mData; } 9}; 10 11class Bar 12{ 13 Foo* mFoo; 14public: 15 Bar() : mFoo(nullptr) { } 16 Bar(Foo* iFoo) : mFoo(iFoo) 17 { 18 std::cout << "new Foo =" << mFoo << std::endl; 19 } 20 ~Bar() 21 { 22 if (mFoo != nullptr) 23 { 24 std::cout << "delete mFoo = " << mFoo << std::endl; 25 delete mFoo; 26 std::cout << "deleted." << std::endl; 27 } 28 } 29 int get() { return (mFoo)?mFoo->get():-1; } 30#if 0 31 Bar& operator=(Bar& iRhs) 32 { 33 mFoo = iRhs.mFoo; 34 iRhs.mFoo = nullptr; 35 return *this; 36 } 37#else 38 Bar& operator=(Bar const& iRhs) 39 { 40 if (this != &iRhs) 41 { 42 delete mFoo; 43 mFoo = new Foo(*iRhs.mFoo); 44 } 45 return *this; 46 } 47#endif 48}; 49 50int main() 51{ 52 Bar bar0(new Foo(123)); 53 Bar bar1; 54 55 std::cout << "bar0 : " << bar0.get() << "\n"; 56 std::cout << "bar1 : " << bar1.get() << "\n"; 57 bar1 = bar0; 58 std::cout << "bar0 : " << bar0.get() << "\n"; 59 std::cout << "bar1 : " << bar1.get() << "\n"; 60}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

そうしないと、上書きする前のオブジェクトは参照不能となって、メモリリークします。

C++は、直接ポインタを扱った場合には、ガベージコレクションなんていう親切なことはしてくれません。

投稿2020/12/18 12:06

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

user012

2020/12/18 13:28

なるほど! 今回の場合はコピー先のmFooにはnullが入ってるから影響はなくて コピー先がアドレスを持ってたらこの記述が必要ということですか。
maisumakun

2020/12/18 13:31

> 今回の場合はコピー先のmFooにはnullが入ってるから影響はなくて どういう意味でしょうか?
user012

2020/12/18 13:48

mainでbar1;として宣言してるので引数なしの場合bar1.mFooにはnullptrが 入るのようになってるのでmFooをdelete mFoo;は効力をあまり発揮しなくて, bar1.mFooがアドレスを持ってる場合効力を発揮すると思ったのですが何か勘違いをしていましたら指摘お願いします、
maisumakun

2020/12/18 22:22

改めて確認してみたら、元のコード自体がよくなかったですね。 Bar(Foo* iFoo)のコンストラクタを使った場合、mFooには外部からのポインタをそのまま受け入れることになります。そして、operator=で素性不明なポインタをdeleteしてしまう危険が生じることとなってしまいます。 (なお、delete nullは何も起こさないことが保証されています)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問