运算符重载<<需要const;产生头痛

时间:2011-02-21 05:35:36

标签: c++ visual-c++ operator-overloading logic

我正在尝试重载operator <<,但它始终需要是const函数。但是,我想更改此重载函数中的值。我该怎么做?

EDIT1:代码存根如下所示:

class Check

{   
public:
    void operator << (boost::any)
    {
        // checks weather the given is hresult,string(filename) or int(line no) 
        // and dump them into the exception object, 
        // There by hresult will initiate the object and int will throw the object.
        // so the input order must be like below
    }
private:
    Exception exception;
};

用法

Check   check;
check << file->open << __FILE__ << __LINE__ ;

EDIT2:这是因为谁曾说过语法不好实现   我不是一个很好的exp。程序员。我只是试图快速解决异常问题。我的动机是它不应该消耗更多的时间,它应该很容易打字。因为我的同事必须使用这个异常类。我试图找到一个解决方案,答案是&lt;&lt;运算符重载。例如,考虑以下示例

1)我的方法

#define INFO __LINE__ << __FILE__
c++
RunAndCheck runAndCheck;

try
{
    runAndCheck << checkVersion() << INFO;
    runAndCheck << file->Open() << INFO;
    runAndCheck << file->rename() << INFO;
}
catch(...)
{
}

2)传统方法

#define INFO __FILE__,__LINE__
try
{
    runAndCheck.check(checkVersion(),INFO);
    runAndCheck.check(file->Open(),INFO);
    runAndCheck.check(file->rename(),INFO);
}
catch(...)
{
}

可能在这个存根中它或多或少相同,但考虑使用win32API的情况。必须检查每个呼叫的异常。在那种情况下,我发现&lt;&lt;重载很容易输入。所以我做了这样的语法

4 个答案:

答案 0 :(得分:7)

operator<<不需要是const函数。

但是,您真正的问题似乎是无效返回类型。要将插入链接在一起,您需要返回*this

答案 1 :(得分:5)

你在这里遇到麻烦的原因是这是对操作符重载的不当使用。运算符重载最好用于这些位置:

  1. 您的类型就像内置类型(例如,数学类型,数组或指针),并且您希望支持类型上的内置运算符。
  2. 您的类型需要支持复制,在这种情况下,您应该实施operator =
  3. 您的类型需要与标准库(如STL或流)接口,在这种情况下,您可能需要实现operator <<进行流插入,或operator <将类型存储在标准容器类中。
  4. 您想要实现一个函数对象,在这种情况下,您应该实现operator ()
  5. 您上面的代码不属于任何这些类别,因此任何使用它都可能会让人感到困惑。例如,如果不熟悉您的项目的人看到这样的事情:

    myCheck << myValue;
    

    他们可能会想“哦,这是某种流插入”或“哦,这是一种数学类型的位移。”但是,在您的情况下,此代码实际上意味着“让检查器对象myCheck验证myValue”。如果这就是你想要做的事情,那么写一些更明确的东西,比如

    myCheck.validate(myValue);
    

    现在,有人查看您的代码可以更好地了解它的工作原理以及它正在尝试做的事情。

    一般来说,在编写代码时要考虑最小惊讶原则 - 代码不应该让你惊讶于它是如何工作的。通过在非标准上下文中使用operator <<,您可能会导致程序员误解您的代码或很难理解它的作用。通过在此和相关上下文中使用命名函数而不是重载运算符来更明确地表达您的意图,使代码更具可读性,并降低代码将人们阅读它的机会绊倒。

    现在,关于你问题的实际答案。 operator <<不要求成为const成员函数。考虑标准流类,如coutofstream;操作

    cout << "Hello, world!" << endl;
    

    当然,通过将新数据推入其中来修改cout,就像操作

    一样
    cout << setfill('0') << left << hex;
    

    通过更改格式标记来修改cout。因此,如果您希望operator <<函数改变数据被推入的对象,请务必继续使其成为非const成员函数。 C ++对任何重载运算符的const ness或非const没有任何期望,所以你应该完全没问题。

答案 2 :(得分:0)

你可能会做错事。发布代码的相关部分,以及更好地总结您尝试做的事情,并获得更多帮助。

话虽这么说,如果你需要修改const对象中的一些数据,你可以做几件事:

  1. 声明您要修改的成员mutable
  2. 使用const_cast<...>(...)从传入的对象中删除const修饰符。
  3. 但很有可能你试图以错误的方式做事。

答案 3 :(得分:0)

您在operator<<对象中将Check作为插件实现。在这种情况下,看起来正确的解决方案是让你的插入操作符实际上是非const,因为在const对象上使用它是没有意义的(因为它改变了逻辑对象状态)。 p>