2010-02-04 17 views
1

那麼,我是新來的運算符重載,我發現這個問題。而不是記錄自己,我寧願問你:DC++運算符重載示例

重點是,我知道如何做簡單的操作符重載,但我面臨堆棧操作的問題。我會盡力把一個相對簡單的例子:

struct dxfdat 
{ 
int a; 
string b; 

/* here is the question */ 
} 

/* use: */ 
dxfdat example; 

example << "lalala" << 483 << "puff" << 1029 << endl; 

"lalala" << 483 << "puff" << 1029 << endl應存放在b

dxfdat& operator<< (T a)和類似的東西的工作與一個參數(example << 7),但我希望它在'cout'時尚。

對不起,太懶惰了。

編輯:

真實的東西......好吧,這是有點麻煩......其實,B不是字符串,而是其他物體的向量,example << "lalala" << 483 << "puff" << 1029 << endl應該僅僅只創建一個目的。

這是我想要什麼(翻譯),但我對如何告訴它何時創建對象不知道(因爲它從左至右排列的,不是嗎?):

struct dxfDato 
{ 
    dxfDato(int c = 0, string v = 0, int t = 0) { cod = c; val= v; ty = t; } 

    int ty; 
    int cod; 
    string val; 
}; 

struct dxfItem 
{ 
    int cl; 
    string val; 
    vector<dxfDato> dats; 
    vector<dxfItem> sons; 

    template <class T> 
    dxfItem &operator<<(const T &t) 
    { 
     dxfDato dd; 
     std::stringstream ss; 
     ss << t; 
     val = ss; 
     dats.push_back(dd); // this way, it creates a lot of objects 
     return d; 
    } 

}; 

dxfItem headers; 

headers << "lalala" << 54789 << "sdfa" << 483 << endl; 
// this should create *just one object* in dats vector, 
// and put everything on string val 

感謝一切,

注:我不得不提取和翻譯了很多東西把它放在這兒,所以我沒有檢查代碼中的錯誤愚蠢的。

(對不起,擴大這麼多,請告訴我,如果我濫用計算器的問題,系統問題)

+0

你到目前爲止嘗試過哪些代碼?請張貼它。 – strager 2010-02-04 10:59:06

+0

@strager: 原始代碼有點混亂。而且,這個問題比我放的更難一些。現在我提出一些關於這個問題的更多信息(也許我應該打開另一個問題,不是嗎?) Thx用於第一次編輯。 – huff 2010-02-04 11:37:35

+0

我很難讀懂你的代碼。你能否爲了清晰起見而重寫代碼和問題? – bdd 2010-02-04 12:24:36

回答

1

這是很容易,不要驚慌:)

你已經認識到這個問題很好:這是非常相似的std::cout - std::endl工作。

你可以這樣做,雖然我會重命名類型,如果你不介意。

struct EndMarker {}; 
extern const EndMarker end; // To be defined in a .cpp 

class Data 
{ 
public: 
    Data(): m_data(1, "") {} 

    // Usual operator 
    template <class T> 
    Data& operator<<(const T& input) 
    { 
    std::ostringstream aStream; 
    aStream << input; 
    m_data.back() += aStream.str(); 
    }; 

    // End of object 
    Data& operator<<(EndMarker) { m_data.push_back(""); } 

private: 
    std::vector<std::string> m_data; 
}; // class Data 

它的工作方式是默認添加當前的最後一個元素,並在末尾推入一個空元素。

讓我們看一個例子:

Data data; 
data << 1 << "bla" << 2 << end << 3 << "foo" << end; 

// data.m_data now is 
// ["1bla2", "3foo", ""] 

其他的解決辦法是保持一個標記(布爾)來存儲,如果end已經流或沒有,如果有,建立在一個新的元素接下來插入(並擦除標誌)。

它插入一點點工作,但你沒有空的元素...你的來電。

7

訣竅是參照從operator <<回到youself - 這樣一來,運營商可以「堆疊」。

class me { 

    me& operator<<(int t) {...; return *this;} 
}; 

me m; 
m << 4 << 5 << 6; 

只是爲所有希望支持的類型超載移位運算符(或者如果可以承擔危險,則使其成爲模板)!

+0

任何方式你可以知道什麼時候是最後一個操作?因爲 - 實際上 - 對象不是一個字符串,而是一個矢量,我必須用info創建一個對象(參見編輯)。 Thx爲您的答覆。 – huff 2010-02-04 11:42:20

+1

我只需添加一個必需的結束元素(類似於'std :: endl')。 – 2010-02-04 11:50:20

+0

這是一個好主意。我會盡力走向那個方向。 不知道是否還有其他方法。 – huff 2010-02-04 11:57:53

2
template <typename T> 
dxfdata & operator <<(dxfdata & d, const T & t) { 
    std::ostringstream os; 
    os << t; 
    d.b += os.str(); 
    return d; 
} 
+0

感謝您的回覆。其實,我正在嘗試類似的意思,即迴歸和兩個參數。雖然我的代碼被嚴重地表達,並且沒有運行......因爲要解決的問題稍微複雜一些,因爲你可以在EDIT中看到...... Thx了! – huff 2010-02-04 11:48:34