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

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

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

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

Q&A

解決済

2回答

3111閲覧

newしたインスタンスをdeepcopyしたい

Tololololo

総合スコア118

C++

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

0グッド

0クリップ

投稿2019/07/26 07:32

編集2019/07/26 07:33

newしたインスタンスをディープコピーしたいのですが、あらかじめポインタとして定義している同型変数にディープコピーをするにはどうすれば良いでしょうか?

clsAにもまた別なポインタとして定義された変数があり、clsA内で任意のタイミングでnewインスタンスを作成し代入している場合を想定しています。

今の所、clsA内にクローン関数を作成してclsAのポインタを返すしかないかなっと思っています。

C++

1class A 2{ 3private: 4 int a; 5 int b; 6 7 // これが任意の処理内でnewにより実態を持たせられているとする 8 // つまりこれもDeepCopyが必要 9 A* smallA; 10}; 11 12int main() 13{ 14 A* a = new A(); 15 A* b; // aをDeepCopyでbへ!! 16 17 /* どうしようか... */ 18 19}

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは。

コピーされる側もメモリを確保する必要があります。
ポインタメンバ変数があるので自動生成されるコピー・コンストラクタ使えないため、自分で定義する必要があります。
下記コードでいけると思います。(コンパイルしていないのでバグっていたらごめんなさい)

C++

1class A 2{ 3private: 4 int a; 5 int b; 6 7 // これが任意の処理内でnewにより実態を持たせられているとする 8 // つまりこれもDeepCopyが必要 9 A* smallA; 10public: 11 A(A const& iRhs) : a(iRhs.a), b(iRhs.b), smallA(nullptr) 12 { 13 if (iRhs.smallA) 14 { 15 smallA = new A(iRhs.smallA); 16 } 17 } 18}; 19 20int main() 21{ 22 A* a = new A(); 23 A* b = new A(*a); 24}

しかし、メモリ・リークしそうでムズムズします。
A*ではなく、なるべくstd::unique_ptr<A>などを使うことをお勧めします。

投稿2019/07/26 08:00

Chironian

総合スコア23272

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

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

Tololololo

2019/07/26 09:00 編集

メンバ変数の中に一つでもポインタ変数が存在すると、ポインタでないメンバ変数もコピーされないということなのでしょうか。 あまりコピーコンストラクタを使うこととクローン関数を独自に作るのと違いがなく、大して恩恵が受けられないような気がします。 (私の言うクローン関数とはclsA内の任意の関数内でclsAのポインタを生成して返すことです。) (イメージ: ) A* A::Clone(){ A* clone = new A(); clone->a = this->a; return clone; } 可読性向上のためにクローン関数を独自に作る方が良い気もしてきます。
Chironian

2019/07/26 09:16

> メンバ変数の中に一つでもポインタ変数が存在すると、ポインタでないメンバ変数もコピーされないということなのでしょうか。 自動生成のコピーコンストラクタは、ポインタ変数のアドレスをそのままコピーします。 コピーした後、コピー元とコピー先のインスタンスの両方をdeleteすると多重開放になります。 これは結構メジャーなトラブルの1つです。 > 可読性向上のためにクローン関数を独自に作る方が良い気もしてきます。 C++では、コピーコンストラクタやコピー代入演算子を定義するのは「デフォルト」です。(何もしなければ原則として自動生成されますし) ですので、clone関数があったら、それとコピー代入演算子は何が違うのだろう?と気になるC++プログラマは少なくないと思います。見てみて事実上同じものだったらがっかりしそうです。 とはいえ、JavaやC#に慣れていてC++に不慣れなプログラマーが多いプロジェクトなら、皆が慣れているcloneで実装するのも有りと思います。その時はコピー/ムーブ・コンストラクタやコピー/ムーブ代入演算子をdeleteしておくことをお勧めします。間違って呼ぶとはまりますから。
Tololololo

2019/07/26 09:22 編集

ありがとうございます がっかりさせたくないのでコピーコンストラクタを使うことにします。
guest

0

コピーコンストラクタの出番ではないかと思います。

A(const A &)というコピーコンストラクタを用意すれば、A* b = new A(*a)のようにできます。

投稿2019/07/26 07:35

maisumakun

総合スコア145184

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

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

Tololololo

2019/07/26 07:37

ありがとうございます
Tololololo

2019/07/26 07:42

この A(const A &object) は一見すると戻りもないインスタンスのアドレスを渡すだけに見えますがコピーコンストラクタが返されるのはC++上の仕様っと捉えて良いのでしょうか
maisumakun

2019/07/26 07:51 編集

C++のコンストラクタは「返り値の型のない」「クラス名と同じ名前」のメソッド、というような体裁を取ります。 本当に戻り値のないメソッドはvoidを付けないとコンパイルが通りません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問