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

发布于 2024-10-18 08:18:21 字数 1460 浏览 1 评论 0 原文

我正在尝试重载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: 这适用于曾经说过语法不好实现的人 我不是一个经验丰富的人。程序员。我只是试图为异常制定一个快速解决方案。我的动机是它不应该花费更多时间,它应该很容易打字。因为我的同事都要使用这个异常类。我试图找到解决方案,答案是<<运算符重载。例如,考虑下面的示例

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 的情况。必须检查每个调用是否有异常。在这种情况下,我发现<<重载很容易输入。所以我做了这样的语法

I am trying to overload operator <<, but it always need to be a const function. However, I want to change values inside this overloaded function. How do I do this?

EDIT1: The code stub is something like below:

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;
};

Usage

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

EDIT2: This is for who ever said that the syntax is not good to implement
I am not a well exp. programmer. I just tried to make a quick solution for exception. My motive is it shouldn't consume more time, it should be easy to type. Because my colleagues have to use this exception class. I tried to find a solution for that, and the answer came as << operator overloading. For example consider the below sample

1) My Method

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

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

2) Traditional method

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

May be in this stub it will be more or less same, but consider a situation where win32API used. There every call must be checked for exception. In that case, I found << overloading is easy to type. So that I made such a syntax

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

书间行客 2024-10-25 08:18:21

operator<< 不需要是 const 函数。

不过,您真正的问题似乎是 void 返回类型。为了将插入链接在一起,您需要返回*this

operator<< doesn't need to be a const function.

Your real problem, though, appears to be the void return type. In order to chain insertions together, you need to return *this.

一指流沙 2024-10-25 08:18:21

您在这里遇到麻烦的原因是这是对运算符重载的不当使用。运算符重载最适合在这些场合使用:

  1. 您的类型的行为类似于内置类型(例如,数学类型、数组或指针),并且您希望支持类型上的内置运算符。
  2. 您的类型需要支持复制,在这种情况下您应该实现operator =
  3. 您的类型需要与 STL 或流等标准库接口,在这种情况下,您可能需要实现用于流插入的运算符 << 或用于实现流插入的运算符 将您的类型存储在标准容器类中。
  4. 您想要实现一个函数对象,在这种情况下您应该实现operator()

您上面的代码不属于这些类别中的任何一个,因此对其的任何使用都可能会使人们感到困惑。例如,如果不熟悉您的项目的人看到这样的内容:

myCheck << myValue;

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

myCheck.validate(myValue);

现在,查看你的代码的人可以更好地了解它是如何工作的以及它试图做什么。

一般来说,在编写代码时请考虑最小惊讶原则 - 代码不应该让您对其工作方式感到惊讶。通过在非标准上下文中使用运算符<<,您可能会导致程序员误解您的代码或很难理解它的作用。在本上下文和相关上下文中,通过使用命名函数而不是重载运算符来更明确地表达您的意图,可以使代码更具可读性,并减少代码让人们阅读时出错的机会。

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

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

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

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

通过更改格式化标志来修改cout一样。因此,如果您希望运算符 << 函数改变数据被推入的对象,请务必将其设为非 const 成员函数。 C++ 对任何重载运算符的常量或非常量没有任何期望,因此您应该完全没问题。

The reason you're having trouble here is that this is an inappropriate use of operator overloading. Operator overloading is best used in these spots:

  1. Your type acts like a built-in type (for example, a mathematical type, array, or pointer), and you want to support the built-in operators on your type.
  2. Your type needs to support copying, in which case you should implement operator =.
  3. Your type needs to interface with a standard library like the STL or streams, in which case you might need to implement operator << for stream insertion or operator < to store your type in the standard container classes.
  4. You want to implement a function object, in which case you should implement operator ().

The code you have above does not fall into any of these categories, and consequently any use of it is likely to confuse people. For example, if someone not well-versed with your project sees something like this:

myCheck << myValue;

They are likely to be thinking "oh, that's some sort of stream insertion" or "oh, that's a mathematical type getting bit-shifted over." However, in your case this code really means "have the checker object myCheck validate myValue." If that's what you want to do, then write something more explicit like

myCheck.validate(myValue);

Now, someone looking over your code can get a much better sense for how it works and what it's trying to do.

In general, think about the Principle of Least Astonishment when writing code - code shouldn't surprise you about how it works. By using operator << in a nonstandard context, you are likely to cause programmers to misinterpret your code or have a hard time understanding what it does. Being more explicit about your intentions by using named functions rather than overloaded operators in this and related contexts makes the code more readable and decreases the chance that the code will trip up people reading it.

Now, as for an actual answer to your question. There is no requirement that operator << be a const member function. Think about the standard streams classes like cout or ofstream; the operation

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

Certainly modifies cout by pushing new data into it, just as the operation

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

Modifies cout by changing the formatting flags. So, if you want your operator << function to mutate the object the data is pushed into, by all means go ahead and make it a non-const member function. C++ doesn't have any expectations about the constness or non-constness of any overloaded operators, so you should be perfectly fine.

天煞孤星 2024-10-25 08:18:21

那你很可能做错了什么。发布代码的相关部分,以及您尝试执行的操作的更好摘要,您将获得更多帮助。

话虽这么说,如果您需要修改 const 对象中的某些数据,您可以执行以下操作:

  1. 声明您要修改的成员 mutable
  2. 使用 const_cast<...>(...) 从传入的对象中删除 const 修饰符。

但很可能您正在尝试以错误的方式做某事。

You're likely doing something wrong then. Post the relevant bits of your code, along with a better summary of what your trying to do, and you'll get more help.

That being said, if you need to modify some data in a const object, there are a couple things you can do:

  1. Declare the member you want to modify mutable.
  2. Use const_cast<...>(...) to remove the const modifier from the passed in object.

But most likely you're trying to do something the wrong way.

清醇 2024-10-25 08:18:21

您将 operator<< 作为插入器实现到我们的 Check 对象中。在这种情况下,正确的解决方案似乎是让插入运算符实际上是非常量的,因为在 const 对象上使用它是没有意义的(因为它正在改变逻辑对象状态) 。

You're implementing operator<< as an inserter into our Check object here. In this case, it looks like the right solution is to just have your insertion operator actually be non-const, since it would be nonsensical to use it on a const object (because it's mutating logical object state).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文