1

私の質問は: STL スタックに関する次のコードは正しいですか?

コードでは、complex は、コンストラクターとデストラクタが定義されたユーザー定義クラスです。1 位以降は複雑なコンストラクタとデストラクタがそれぞれ 5 回呼び出され、2 位以降は pop() によって再び複雑なデストラクタが 5 回呼び出されます。したがって、全体として、デストラクタはコンストラクタよりも多く呼び出されます。IMOそれは起こらないはずです。私のコードは正しいですか?正しくない場合、それを修正する方法は?スタックではなくスタックをまだ使用しているとします

#include <stack>  
#include "complex.h"  
using namespace std;   
void test_stack(){   
stack<complex> mystack2;      
cout << "Pushing complex..." << endl;  
 for (int i=0; i<5; ++i) {   
  complex c(i,i);     
  mystack2.push(c);   
 }  
 //place 1  
 cout << "Popping out complex..." << endl;   
 while (!mystack2.empty()) 
 {  
    cout << " " << mystack2.top();  
    mystack2.pop(); //void pop();  
 }  
 //place 2  
 cout << endl;  
}  
4

3 に答える 3

1

で呼び出されるコピーコンストラクターを考慮していない可能性があります

mystack2.push(c);

のような値型クラスのcomplex場合、独自に定義しない場合、コピー コンストラクターが自動的に作成されます。

次のようなコピー コンストラクターを作成できます。

complex( complex const & other )
 : real(other.real)
 , imag(other.imag)
{
   cout<<"complex::copy_constructor called"<<endl;
}
于 2013-05-08T00:31:12.397 に答える
1

元の質問に答えるために、コードに問題はありません。しかし、あなたの理解は少しずれています。

他の人が指摘したように、のコピーコンストラクターmystack2.push(c)を呼び出します。complexしたがって、合計で、コンストラクターへの呼び出しが 5 回、コピー コンストラクターへの呼び出しが 5 回、デストラクタへの呼び出しが 10 回あります。

これは、いくつかの重要なポイントをもたらします。お気づきのように、次のコード:

for (int i=0; i<5; ++i) {   
    complex c(i,i);     
    mystack2.push(c);   
}

最初にcomplex(c) を作成し、次にコピーをスタックに追加します。c がスコープ外になると、元の複合体は破棄されます。C++11 では、余分なコピーは不要で、次のことができます。

for (int i=0; i<5; ++i) {   
    mystack2.emplace(i, i); 
}  

これにより、スタックがオブジェクトの構築を行い、コピーの必要がなくなります。

コンストラクターが10回呼び出されたというあなたの混乱につながったと私が思うもう1つの点complexは、コンストラクターとデストラクタのみを定義すると言ったことです。コピー コンストラクターを定義しない場合 (およびそれをプライベートまたは削除済みとしてマークしない場合)、コンパイラーによって自動的に作成されます。実際には、C++11 の場合よりも少し多くのことが必要です。詳細については、この質問を参照してください - Conditions for automatic generation of default/copy/move ctor and copy/move assignment operator? . ただし、注意すべき重要なことは、この場合、 へのpush呼び出しは、コンパイラによって生成されたコピー コンストラクターを呼び出していることです。

于 2013-05-08T00:44:50.120 に答える