类成员函数是否存在流运算符?

时间:2019-02-10 22:32:13

标签: c++ oop

我将boost记录器包括在内。我很高兴它是如何工作的。出于简单性以及出于我不想在代码中频繁使用makros的原因,我将其包装在一个类中。

我现在想知道是否可以使用流操作符<<编写成员函数。

代码

class LogWrapper{
    ...
    //debug function
    //info function
    ...
}

void main() {
    LogWrapper log;
    log.debug() << "some debug msg"; // does this exist?
    log.info() << "some info msg";
}

输出

[some_timestamp][debug]  some debug msg
[some_timestamp][info]   some info msg

这是好的做法,还是完全不好的风格?

2 个答案:

答案 0 :(得分:2)

可以很容易地做到这一点:

#include <iostream>

class A {
  public:
    std::ostream &debug() const {
      std::cerr << "[timestamp]" << "[DEBUG]";
      return std::cerr;   
    }
};

int main()
{
    A a;
    a.debug() << "Test";
}

但是这里的重要问题是:我们应该以这种方式实现它吗?我认为不!

因为您认为该类的用户将打印日志,如下所示:

int main()
{
    A a;
    a.debug() << "Test" << std::endl;
    a.debug() << "Test2" << std::endl;
}

输出:

[timestamp][DEBUG]Test
[timestamp][DEBUG]Test2

但是如果用户选择这种方式怎么办:

int main()
{
    A a;
    auto &out = a.debug();
    out << "Test" << std::endl;
    out << "Test2" << std::endl;
}

输出:

[timestamp][DEBUG]Test
Test2

我强烈建议不要返回流对象。为此,您应该使用成员函数。

#include <iostream>

class A {
  public:
    static void debug(const std::string &log) {
      std::cerr << "[timestamp]" << "[DEBUG]" << log << std::endl;
    }
};

int main()
{
    A::debug("Test 1");
    A::debug("Test 2");
}

输出:

[timestamp][DEBUG]Test 1
[timestamp][DEBUG]Test 2

答案 1 :(得分:-1)

我不认为这是存在的,因为当您写:

int nb = a.funcFoo() + a.funcBar();

如果a.funcFoo()返回值为3的整数,而a.funcBar()返回值为5的整数,则这两个函数中的代码将预先执行,然后将它们“替换”在表达式中按其返回值显示,

int nb = 3 + 5;

所以这意味着在您的情况下,a.func()被其返回值替换:

(your returned value) << "test";

如果要让流运算符对返回的值进行操作,则可能会重载流运算符,重载运算符使您可以定义运算符根据之前和之后的行为进行操作。 有关更多信息:https://en.cppreference.com/w/cpp/language/operators

看着您添加的注释,我仍然不太了解您想做什么,但是我认为仅使用参数和函数重载就应该有可能。 函数重载使您可以创建具有不同参数但名称相同的多个函数。

例如(使用您的班级名称):

void ClassA::test(std::string const &str)
{
    std::cout << "We received a string!" << std::endl;
}

void ClassA::test()
{
    std::cout << "We received nothing..." << std::endl;
}

这两种方法之一取决于test()函数是接收字符串还是没有接收任何参数。

例如,如果您愿意,可以这样做:

void ClassA::func(std::string const &debugMessage)
{
    std::cerr << "DEBUG: " << debugMessage << std::endl;
    func();
}

void ClassA::func()
{
    //Do stuff
}

在这里,如果您使用字符串作为参数调用func()函数,它将显示一条调试消息,然后它将调用不带任何参数的func()函数,但您也可以调用func() )函数,不带任何参数,并且不会出现调试消息! 有关更多信息:https://www.geeksforgeeks.org/function-overloading-c/