C ++运算符重载示例

时间:2010-02-04 10:56:39

标签: c++ operator-overloading

好吧,我是操作员重载的新手,我发现了这个问题。我不想记录自己,而是问你:D

关键是,我知道如何进行简单的运算符重载,但我遇到了堆栈运算符的问题。我将尝试举一个相对简单的例子:

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应该只创建一个对象。 / p>

这就是我正在尝试(翻译)的内容,虽然我不知道如何告诉它何时创建对象(因为它从左到右,不是吗?):

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

感谢您的一切,

注意:我必须提取并翻译很多东西才能把它放在这里,所以我没有检查代码是否有愚蠢的错误。

(很抱歉扩大这个问题,如果我误用了stackoverflow的问题系统,请告诉我)

3 个答案:

答案 0 :(得分:7)

诀窍是从operator <<返回对你自己的引用 - 这样,操作符可以“堆叠”。

class me {

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

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

只需为你想要支持的所有类型的移位操作符重载(或者如果你能负担危险就把它变成模板)!

答案 1 :(得分:2)

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

答案 2 :(得分: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是否已经流式传输,如果有,则在下次插入时创建一个新元素(并删除标志)。

在插入方面还有一些工作要做,但你没有空元素......你的电话。