質問するログイン新規登録
C++

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

Q&A

解決済

1回答

816閲覧

デストラクタが2回呼ばれている

umehara

総合スコア6

C++

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

0グッド

0クリップ

投稿2023/06/10 15:45

0

0

実現したいこと

下記コードを実行するとデストラクタが2回呼ばれております
(x1 → z → x2→ x2という順番で出力される)
なぜ2回呼ばれているのかがわからないです
どこかでデフォルトコンストラクタ生成が行われているのでしょうか?

該当のソースコード

c++

1class Param 2{ 3public: 4 Param() { printf("x1\n"); }; 5 ~Param() { printf("x2\n"); }; 6 7}; 8 9void ppp(Param p) 10{ 11 printf("z\n"); 12} 13int main() 14{ 15 ppp(Param()); 16 17}

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

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

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

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

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

guest

回答1

0

ベストアンサー

引数は特に指定しなければ値が「コピー」される形で渡されます。

たとえば

cpp

1#include <cstdio> 2 3void foo(int p) { 4 p = 2; 5} 6 7int main(void) { 8 int x = 1; 9 foo(x); 10 std::printf("%d\n", x); 11}

というように書いたとき p に何を代入しても x の内容は何も変わりません。 xp は違う存在だからです。

質問の事例では main 内の Param() という式で一時的なオブジェクトが生成された上でそれをコピーする形で p が生成されるので、生成されるオブジェクトはふたつです。 コピーのときには「暗黙に生成されたコピーコンストラクタ」が使われるのでデフォルトコンストラクタは呼ばれません。

しかし質問の事例はコピーの省略 (copy elision) が許される (してもしなくてもよい) 場合に該当し、かつ C++17 以降はコピーを省略しなければならない場合です。 なのでデストラクタも一回しか呼ばれないかもしれません。

C++ の仕様は選択肢を設けていることも多いので処理系によって (あるいは場合によって) 異なる結果を許すこともありますし、また、改定されることもあるのでバージョンによって解釈が異なる場合もあることは注意を払う必要があります。 改訂年の下二桁を取ってたとえば 2011 年の規格を C++11 と呼ぶのが通例です。

投稿2023/06/10 16:19

SaitoAtsushi

総合スコア5740

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

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

umehara

2023/06/18 02:06

返答ありがとうございます 引数はコピーなのでコピーコンストラクタが呼ばれるの失念していました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問