2012-02-29 132 views
1

我想在我創建的類中使用stdlib堆棧,但我在動態創建它時遇到問題。動態分配stdlib堆棧?

這裏是我的頭文件「matcher.h」的相關代碼:

private: 

     stack<char> opens; 

這裏是我創建僅分配堆棧的構造:

#include "matcher.h" 
using namespace std; 
//Creates a matcher object with the default values. 
matcher::matcher() 
{ 
    opens = new stack<char>; 
} 

錯誤我得到低於:

matcher.cpp:19:17: error: no match for ‘operator=’ in ‘((matcher*)this)->matcher::opens = ((*(const std::deque<char, std::allocator<char> >*)(& std::deque<char, std::allocator<char> >())), (operator new(40u), (<statement>, ((std::stack<char>*)<anonymous>))))’ 

這對我說了std::stack確實ñ不包含一個賦值運算符,這導致我到我的問題:

我應該使用什麼方法來獲得一個堆棧,如果它不包含賦值運算符將保留在我的匹配器對象中?

謝謝你的時間。

+2

從Java或C#轉換時,您需要一個C++課程。 – 2012-02-29 17:46:52

+0

我想教自己:) – Joshua 2012-02-29 22:11:43

回答

3

opens是該類中的一個對象,因此不需要使用new進行分配。

如果你希望它是默認構造的,那麼這將自動發生 - 你不需要編寫任何代碼來做到這一點。如果所有的類成員都可以默認構造,那麼你就不需要爲這個類編寫一個默認構造函數。

如果你不能(或不應該)被默認構造一員,那麼你就做,在構造函數的初始化器列表,例如:

class matcher { 
public: 
    matcher() : 
     number(42) // initialise with a value 
    {}    // nothing else to do - "opens" is automatically initialised 

private: 
    stack<char> opens; 
    int number; 
}; 

僅使用new當你真正需要一個動態分配的對象,並確保一旦你完成它的刪除 - 最好使用RAII,因爲通常很難以任何其他方式正確地將其刪除。如果您希望將其綁定到另一個對象的生命週期中,那麼只需將其作爲成員放入該類中,而不用擔心動態分配。

+0

是的,謝謝。出於某種原因,我認爲你需要在創建課程時分配它。 – Joshua 2012-02-29 22:13:17

2

new總是返回一個指針爲您指定的類型。 opens需要是stack<char> *

但是你確定需要動態分配堆棧嗎?您可以在構造函數中創建的私有成員變量很少需要動態分配。如果你真的動態分配它,你應該在一個析構函數中使用delete

1

您正在分配新的結果,這將是一個指向堆棧的指針。換句話說,您正試圖將堆棧*分配給堆棧。

其次,你爲什麼要這樣做?無論如何,堆棧會分配它的元素。不需要新的。

1

您不能將stack<char>*(即new stack<char>返回)分配給stack<char>變量。相反,你應該使用下面的構造函數:

// look ma, no need for new! 
matcher::matcher() 
{ 
} 

,只是依靠opens默認的初始化。當您的matcher對象時,堆棧將被適當銷燬。

0

這裏至少有兩個問題。

private: 
    stack<char> opens; 

這意味着你要麼在你的頭一個using namespace std;(極其惡劣的形式),或者您需要一個有using namespace std;聲明包括頭部(甚至更糟糕的形式)前。

另一個問題是編譯器錯誤的直接原因。您不應該分配該堆棧。要分配opens需要聲明它爲std::stack<char>* opens; - 這也是你通常不想做的事情。隨着聲明的原樣,std::stack<char> opens;,該變量已存在。它只是需要構建。如果您不指定如何在構造函數的初始化程序列表中構造對象,則缺省情況下將使用默認構造函數。