C++ 中的 const 正确性运算符重载返回

发布于 2024-08-12 08:31:15 字数 600 浏览 4 评论 0原文

我有点困惑为什么我被告知要从 C++ 中的二元运算符返回 const foo 而不仅仅是 foo。

我一直在阅读 Bruce Eckel 的《Thinking in C++》,在关于运算符重载的章节中,他说“通过将[重载二元运算符]的返回值设置为 const,您可以声明只有 const 成员函数可以被调用以获取该返回值。这是常量正确的,因为它可以防止您将潜在有价值的信息存储在很可能丢失的对象中”。

但是,如果我有一个返回 const 的加号运算符和一个前缀增量运算符,则此代码无效:

class Integer{
int i;

public:
    Integer(int ii): i(ii){ }
    Integer(Integer&);

    const Integer operator+();
    Integer operator++();
};


int main(){

Integer a(0);
Integer b(1);

Integer c( ++(a + b));
}

为了允许这种赋值,让 + 运算符返回一个非常量值不是有意义吗?这可以通过添加 const_casts 来完成,但这会变得相当庞大,不是吗?

谢谢!

I'm a little confused as to why I've been told to return const foo from a binary operator in c++ instead of just foo.

I've been reading Bruce Eckel's "Thinking in C++", and in the chapter on operator overloading, he says that "by making the return value [of an over-loading binary operator] const, you state that only a const member function can be called for that return value. This is const-correct, because it prevents you from storing potentially valuable information in an object that will be most likely be lost".

However, if I have a plus operator that returns const, and a prefix increment operator, this code is invalid:

class Integer{
int i;

public:
    Integer(int ii): i(ii){ }
    Integer(Integer&);

    const Integer operator+();
    Integer operator++();
};


int main(){

Integer a(0);
Integer b(1);

Integer c( ++(a + b));
}

To allow this sort of assignment, wouldn't it make sense to have the + operator return a non-const value? This could be done by adding const_casts, but that gets pretty bulky, doesn't it?

Thanks!

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

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

发布评论

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

评论(4

虐人心 2024-08-19 08:31:15

当您说 ++x 时,您是在说“将 1 添加到 x,将结果存储回 x,然后告诉我它是什么”。这是预自增运算符。但是,在 ++(a+b) 中,你应该如何“将结果存储回 a+b”?

当然,您可以将结果存储回当前保存 a+b 结果的临时存储器中,该临时存储器很快就会消失。但是,如果您并不真正关心结果存储在哪里,为什么要增加它而不是只加一呢?

When you say ++x, you're saying "add 1 to x, store the result back into x, and tell me what it was". This is the preincrement operator. But, in ++(a+b), how are you supposed to "store the result back into a+b"?

Certainly you could store the result back into the temporary which is presently holding the result of a+b, which would vanish soon enough. But if you didn't really care where the result was stored, why did you increment it instead of just adding one?

嘴硬脾气大 2024-08-19 08:31:15

仅供参考,即使对于 POD(普通旧数据类型,例如 int),++(a + b) 也是非法的。因此,不允许您自己的类类型使用它也是有道理的。试试这个:

int a = 1;
int b = 2;
int c = ++(a+b);

GCC 返回错误:需要左值作为增量操作数

在您的情况下,最好让您的复制构造函数采用 const Integer 参数,并像这样创建您的 Integer c :

Integer c(a + b + Integer(1));

FYI, ++(a + b) is illegal even with PODs (plain old data types, like int). So it makes sense not to allow it for your own class types either. Try this:

int a = 1;
int b = 2;
int c = ++(a+b);

GCC returns error: lvalue required as increment operand.

In your case, it would be preferable make your copy constructor take a const Integer argument, and create your Integer c like this instead:

Integer c(a + b + Integer(1));
过度放纵 2024-08-19 08:31:15

复制构造函数通常采用 const 引用,为您解决该问题。

(拥有非常量复制构造函数意味着一些资源转移,这有时很有用,但对于 99% 的情况,不需要)

Copy constructors usually take a const reference, solving that problem for you.

(Having non-const copy ctor implies some transfer of resources, which can be useful sometimes, but for 99% of all situations, it's not needed)

維他命╮ 2024-08-19 08:31:15

我相信OP的例子将适合这个问题,如果加法运算符被任何其他返回引用的二元运算符替换,例如赋值运算符:

Integer c( ++(a = b));

我来这里想知道我是否应该让我的赋值运算符返回一个const或一个非-常量参考。 一些教程 使用非常量版本,这与“Thinking in C++”的建议相反。 一些其他参考文献给出了背后的推理:

请注意,返回的引用未声明为 const。这可能有点令人困惑,因为它允许您编写如下疯狂的东西:

<块引用>

MyClass a、b、c;

...

(a = b) = c; // 什么??

乍一看,您可能希望通过让 operator= 返回 const 引用来防止出现此类情况。但是,这样的语句适用于原始类型。更糟糕的是,一些工具实际上依赖于这种行为。因此,从运算符 = 返回非常量引用非常重要。经验法则是,“如果它对于整数足够好,那么对于用户定义的数据类型也足够好。”

I believe OP's example would be suitable to the question if the addition operator is substituted with any other binary operator that returns a reference, for example an assignment operator:

Integer c( ++(a = b));

I came here wondering whether I should make my assignment operator return a const or a non-const reference. Some tutorials use non-const versions, contrary to "Thinking in C++"'s advice. And some other references give reasoning behind that:

Notice that the returned reference is not declared const. This can be a bit confusing, because it allows you to write crazy stuff like this:

MyClass a, b, c;

...

(a = b) = c; // What??

At first glance, you might want to prevent situations like this, by having operator= return a const reference. However, statements like this will work with primitive types. And, even worse, some tools actually rely on this behavior. Therefore, it is important to return a non-const reference from your operator=. The rule of thumb is, "If it's good enough for ints, it's good enough for user-defined data-types."

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