簡體   English   中英

如何在STL堆棧中保存用戶定義的類型?

[英]how to hold user defined type in STL stack?

我的問題是:關於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;  
}  

為了簡化它,我不會提到每個都發生了5次:

  • complex c(i,i); - 構造函數調用
  • mystack2.push(c); - 構造函數調用
  • c超出范圍 - 析構函數稱為
  • mystack2.pop(); - 析構函數叫

注意:要查看正在進行的操作,請在構造函數和析構函數中添加跟蹤消息。 不要忘記三個規則。

您可能沒有考慮將被調用的復制構造函數

mystack2.push(c);

對於像complex這樣的值類型類,如果您沒有定義自己的復制構造函數,將自動為您創建。

您可以使用以下內容創建復制構造函數:

complex( complex const & other )
 : real(other.real)
 , imag(other.imag)
{
   cout<<"complex::copy_constructor called"<<endl;
}

要回答您的原始問題,您的代碼沒有任何問題。 但是,你的理解有點偏差。

正如其他人所說, 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次的困惑,就是你說complex只定義了一個構造函數和一個析構函數。 如果您沒有定義復制構造函數(並且不將其標記為私有或已刪除),則編譯器將自動創建一個復制構造函數。 實際上它比C ++ 11還要多一些,我會引導你到這個問題的細節 - 自動生成默認/復制/移動ctor和復制/移動賦值運算符的條件? 但是,需要注意的重要一點是,在這種情況下,對push調用肯定是調用編譯器生成的復制構造函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM