[英]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.