2017-08-25 34 views
3

は、次のコードを考えてみましょう:C++ - デストラクタが予想以上回呼び出され

class C1 
{ public: 

     C1(){ cout<<"CONSTR WAS HERE"<<endl; } 

     C1(const C1&ob){ cout<<"COPY CONSTR WAS HERE"<<endl; } 

     ~C1(){ cout<<"DESTR WAS HERE"<<endl; } 
} 

void f1(C1 x){ } 

int main() 
{ 
    C1 c1; 
    f1(c1); 
} 

そのまま私たちは、コードを実行すると、我々が得る:

から完全に理解できる
CONSTR WAS HERE 
COPY CONSTR WAS HERE 
DESTR WAS HERE 
DESTR WAS HERE 

私の視点。

C1のF1(C1 X){}

代わりに

空隙F1(C1 X){}

:しかし、我々は、 "F1" 機能を変更し、場合

は、我々が得る:

CONSTR WAS HERE 
COPY CONSTR WAS HERE 
DESTR WAS HERE 
DESTR WAS HERE 
DESTR WAS HERE 

と私はなぜそれほど確かではありません。

+11

'C1 f1(C1 x){}'は実際には値を返さないため、未定義の動作をします。 – AndyG

+0

何かを返す関数を宣言した場合(戻り値の型が 'void'以外の場合)、*関数は*何かを返さなければなりません。そうしないと、*未定義の動作*(http://en.cppreference。 com/w/cpp/language/ub)(これはあなたのプログラムを不正な形式にして無効にします)。 UBを使ってプログラム内のあらゆる種類の行動を推測することは、議論の対象となります。 –

答えて

12

あなたの警告を有効にしない:

警告:何かが起こることができることを意味しますが、あなたのプログラムにundefined behaviorを持つ非空[-Wreturn型]

を返す関数にはreturn文を。コンパイラは、 "C1の定義されていないインスタンスをここに返す"と思われます。これにより、デストラクタが呼び出されます。

コンパイラ/フラグ/マシンによっては、プログラムがクラッシュするか、何か他のものがあります()。

9

変更C1 f1(C1 x){}は、実際に何かを返すようにして、出力は(Demo

C1 f1(C1 x){ return {};} 

コンストラクタが
コピーコンストラクタが
コンストラクタが
DESTRはHERE
WAS HERE WAS HERE WAS HERE WAS予想通りとなりますここにはDESTR WAS HERE
DESTR WAS HEREここに

それ以外の場合、コードは未定義の動作を示します。

関連する問題