重载运算符<<作为会员印刷

时间:2011-12-12 14:36:20

标签: c++ operator-overloading iostream

有没有办法重载<< operator,作为类成员,将值打印为文本流。如:

class TestClass {
public:
    ostream& operator<<(ostream& os) {
        return os << "I'm in the class, msg=" << msg << endl;
    }

private:
    string msg;
};


int main(int argc, char** argv) {
    TestClass obj = TestClass();
    cout << obj;

    return 0;
}

我能想到的唯一方法是在课堂外重载操作员:

ostream& operator<<(ostream& os, TestClass& obj) {
    return os << "I'm outside of the class and can't access msg" << endl;
}

但是,访问对象私有部分的唯一方法是与操作员函数联系,如果可能的话我宁愿避开朋友,因此请求您提供替代解决方案。

有关如何进行的任何意见或建议都会有所帮助:)

6 个答案:

答案 0 :(得分:8)

它必须是非成员,因为类形成运算符的第二个参数,而不是第一个参数。如果输出只能使用公共接口完成,那么就完成了。如果它需要访问非公开成员,那么你必须声明它是朋友;这就是朋友们的目的。

class TestClass {
public:
    friend ostream& operator<<(ostream& os, TestClass const & tc) {
        return os << "I'm a friend of the class, msg=" << tc.msg << endl;
    }

private:
    string msg;
};

答案 1 :(得分:6)

我认为一种流行的方法是在会员中调用公共非虚拟operator<<方法的非会员,非朋友免费print。此打印方法可以执行工作或委托给受保护的虚拟实现。

class TestClass {
public:
    ostream& print(ostream& os) const {
        return os << "I'm in the class, msg=" << msg << endl;
    }

private:
    string msg;
};


ostream& operator<<(ostream& os, TestClass& obj) {
    return obj.print(os);
}

int main(int argc, char** argv) {
    TestClass obj;
    cout << obj;

    return 0;
}

答案 2 :(得分:5)

您偶然发现了实现此功能的规范方法。你有什么是正确的。

答案 3 :(得分:1)

您可以将其设为班级的成员,位于<<的左侧,在您的情况下为ostream

但是,你可以做的是,有一个基类,void do_stream(ostream& o);成员用于你所有的流量和非成员operator<<,可以调用它。

答案 4 :(得分:0)

你是对的,这是实现流操作符的唯一方法 - 在课外。

您需要将方法声明为friend

这就是它的完成方式。

答案 5 :(得分:0)

你必须使它成为非成员(因为第一个参数不是你的类)。

但你可以把它写在你的班级定义中(作为朋友):

class TestClass
{
public:
    // Have a nice friend.
    // This tightly binds this operator to the class.
    // But that is not a problem as in reality it is already tightly bound.
    friend ostream& operator<<(ostream& os, TestClass const& data)
    {
        return os << "I'm in the class, msg=" << data.msg << endl;
    }

private:
    string msg;
};

我觉得把这个变成朋友是没有错的。