const 重载的operator[]函数及其调用

发布于 2024-11-03 03:17:32 字数 499 浏览 0 评论 0原文

我在类array 中定义了两个版本的重载operator[] 函数。 ptr 是指向array 对象的第一个元素的指针。

int& array::operator[] (int sub) {  
   return ptr[sub];
} 

现在

int array::operator[] (int sub) const { 
  return ptr[sub];
}

,如果我定义一个 const 对象 integer1 ,则只能调用第二个函数......但是如果我创建一个非 const 对象,然后按如下方式调用:

cout << "3rd value is" << integer1[2];

这里调用哪个函数?

I define two versions of overloaded operator[] function in a class array. ptr is a pointer to first element of the array object.

int& array::operator[] (int sub) {  
   return ptr[sub];
} 

and

int array::operator[] (int sub) const { 
  return ptr[sub];
}

Now, if I define a const object integer1 the second function can only be called..... but if I make a non-const object and then invoke as below:

cout << "3rd value is" << integer1[2];

which function is called here?

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

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

发布评论

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

评论(2

戴着白色围巾的女孩 2024-11-10 03:17:33

在第二个示例中,将调用非常量版本,因为不需要转换,并且不需要转换的调用比需要转换的调用更匹配。

然而,最终,您遇到了一个基本问题:您真正想要的是根据您将对象用作右值还是左值而变化的行为,而 const 并没有真正做到这一点。为了使其正常工作,您通常需要返回一个代理对象,并为代理对象重载 operator=operator T

template <class T>
class myarray { 
    T *ptr;

    class proxy { 
        T &val;
        proxy &operator=(proxy const &p); // assignment not allowed.
    public:
        proxy(T &t) : val(t) {}
        operator T() const { return val; }
        proxy &operator=(T const&t) { val = t; return *this; }
    };

    proxy const operator[](int sub) const { return proxy(ptr[sub]); }
    proxy operator[](int sub) { return proxy(ptr[sub]); }
    // obviously other stuff like ctors needed.
};

现在我们得到了正常的行为 - 当/如果我们的array(或任何类型)是const,我们的operator[] const将被使用,并且它会给出一个const代理代码>.由于其赋值运算符不是 const,因此尝试使用它们将会失败(无法编译)。

OTOH,如果原始 array 不是 const,我们将得到一个非常量代理,在这种情况下,我们可以同时使用 operator Toperator=,并且能够读取和写入array中的值。

In your second example, the non-const version will be called, because no conversion is required, and a call that requires no conversion is a better match than one that requires a conversion.

Ultimately, however, you have a basic problem here: what you really want is behavior that changes depending on whether you're using your object as an rvalue or an lvalue, and const doesn't really do that. To make it work correctly, you normally want to return a proxy object, and overload operator= and operator T for the proxy object:

template <class T>
class myarray { 
    T *ptr;

    class proxy { 
        T &val;
        proxy &operator=(proxy const &p); // assignment not allowed.
    public:
        proxy(T &t) : val(t) {}
        operator T() const { return val; }
        proxy &operator=(T const&t) { val = t; return *this; }
    };

    proxy const operator[](int sub) const { return proxy(ptr[sub]); }
    proxy operator[](int sub) { return proxy(ptr[sub]); }
    // obviously other stuff like ctors needed.
};

Now we get sane behavior -- when/if our array<int> (or whatever type) is const, our operator[] const will be used, and it'll give a const proxy. Since its assignment operators are not const, attempting to use them will fail (won't compile).

OTOH, if the original array<int> was not const, we'll get a non-const proxy, in which case we can use both operator T and operator=, and be able to both read and write the value in the array<int>.

默嘫て 2024-11-10 03:17:33

您的 const 版本应返回 const int& 而不是 int,以便两个函数之间的语义完全相同

一旦完成此操作,使用哪一个就不再重要了。如果因为您的对象具有 const 上下文而必须使用 const 版本,那么它将......并且这并不重要,因为您没有尝试修改任何内容。否则,它将使用非 const 版本...但效果相同。

Your const version should return const int& not int, so that the semantics are just the same between the two functions.

Once you've done that, it doesn't matter which one is used. If the const version has to be used because your object has a const context, then it will be... and it won't matter as you're not trying to modify anything. Otherwise, it'll use the non-const version... but with just the same effect.

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