过载运算符<<

时间:2016-04-17 00:53:30

标签: c++ c++11 operator-overloading

我想像这样重载fixture.detectChanges();

operator<<

以便将ostringstream oss; MyDate a(2000, 1, 2); oss << dateFormat("%Y/%m/%d") << a; assert(oss.str() == "2000-01-02"); 的日期格式化为特定格式。怎么做到这一点?

2 个答案:

答案 0 :(得分:3)

为了在流中存储自定义状态,您需要使用xalloc静态函数来获取唯一索引,然后使用pword来获取该索引处的指针(专门为它用于的每个流,或iword在该索引处获得一个整数(专门为其使用的每个流分配)​​。在您的情况下,您可能需要pword。您可以使用pword返回的指针指向存储格式信息的动态分配对象。

struct DateFormatter
{
    // The implementation of this class (e.g. parsing the format string)
    // is a seperate issue. If you need help with it, you can ask another
    // question

    static int xalloc_index;
};

int DateFormatter::xalloc_index = std::ios_base::xalloc();

void destroy_date_formatter(std::ios_base::event evt, std::ios_base& io, int idx)
{
    if (evt == std::ios_base::erase_event) {
        void*& vp = io.pword(DateFormatter::xalloc_index);
        delete (DateFormatter*)(vp);
    }
}

DateFormatter& get_date_formatter(std::ios_base& io) {
    void*& vp = io.pword(DateFormatter::xalloc_index);
    if (!vp) {
        vp = new DateFormatter;
        io.register_callback(destroy_date_formatter, 0);
    }
    return *static_cast<DateFormatter*>(vp);
}

std::ostream& operator<<(std::ostream& os, const DateFormatter& df) {
    get_date_formatter(os) = df;
    return os;
}

std::ostream& operator<<(std::ostream& os, const MyDate& date)
{
    DateFormatter& df = get_date_formatter(os);

    // format output according to df

    return os;
}

int main() {
    MyDate a ( 2000, 1, 2 );
    std::cout << DateFormatter("%Y/%m/%d") << a;
}

这是标准方法。在我看来,这太可怕了。我更喜欢另一种方法,即将日期对象与格式作为单个对象一起传递。例如:

class DateFormatter
{
    const MyDate* date;
    std::string format_string;
    DateFormatter(const MyDate& _date, std::string _format_string)
        :date(&_date)
        ,format_string(_format_string)
    {}

    friend std::ostream& operator<<(std::ostream& os, const DateFormatter& df) {
        // handle formatting details here
        return os;
    }
};

int main() {
    MyDate a ( 2000, 1, 2 );
    std::cout << DateFormatter(a, "%Y/%m/%d");
}

答案 1 :(得分:0)

或者你可以做那样的事情(使用静态变量):

#include <iostream>

struct MyDate
{
    MyDate(int y, int m, int d): year{y}, month{m}, day{d} {}

    int year{};
    int month{};
    int day{};
};

class DateFormatter
{
public:
    DateFormatter(const std::string & format)
    {
        format_ = format;
    }

    static const std::string & format()
    {
        return format_;
    }

private:
    static std::string format_;
};

std::string DateFormatter::format_ = {"Default Format"};

std::ostream & operator<< (std::ostream & stream, const DateFormatter &)
{
    return stream;
}

std::ostream & operator<< (std::ostream & stream, const MyDate & date)
{
    auto currentFormat = DateFormatter::format();
    // some code using current format ...
    return stream << currentFormat << " - " << date.year << "/" << date.month << "/" << date.day;
}

int main(void)
{
    MyDate date{2016,4,18};
    std::cout << date << std::endl;
    std::cout << DateFormatter("New format") << date << std::endl;

    return 0;
}