C++ Operator []重载SNAFU

It'*_*ete 2 c++ const operator-overloading

我有一个类,我想定义[]运算符.该类保存一个串行数据包(以及对所述数据包进行操作的相关功能).我想让用户有能力做这样的事......

MyClass packet;
uint8_t byte = packet[3];  // get third byte of packet
Run Code Online (Sandbox Code Playgroud)

我想阻止用户这样做......

packet[3] = 0xAA;  // this breaks encapsulation for my class :(
Run Code Online (Sandbox Code Playgroud)

我一直在寻找解决方案,我想知道这个声明是否就是我所需要的(以及我的.cpp中的相关代码):

const uint8_t operator[](const std::size_t index) const;
Run Code Online (Sandbox Code Playgroud)

虽然我很确定这会起作用,但我仍然对我的方法有一些不确定性,我希望你能解决我的问题.

  1. 简单地返回值而不是引用是"可以"吗?我知道在我看过的所有例子中都返回了一个引用.返回值是否有助于我解决这个事实,即我不希望在操作的左侧使用"[]"?那么,const不会阻止这个吗?

  2. 即使在非const对象上也会调用const函数吗?我已经看到了一些例子,其中有一个const版本的运算符和一个非const的运算符声明.非const允许写入,而const只允许读取,但只调用const对象.我的目标是让非const对象只能读取.

  3. 是否有一种干净的方法来传递操作员的错误?我的主要问题是所请求的数据可能超出了我所拥有的数据范围.我见过的所有示例都使用了断言,但是如果用户对运算符的调用导致某种程度的欢闹,我不一定希望程序崩溃.我也不一定能传回特殊代码,因为我传回的字节的任何值都可能有效.

一如既往,感谢您的帮助,因为我慢慢地(但肯定地)从C程序员到OO C++向导进行了可怕的过渡.

AnT*_*AnT 7

  1. 是的,只需返回一个值就可以了uint8_t.你可以返回一个const引用,const确实会阻止任何人通过它来写.但是对于像uint8_t价值返回这样的小类型来说是一个更好的主意.注意,BTW,当按值返回时,您不再需要const返回类型.

    返回一个const引用,即使它很难阻止修改,也使调用代码能够创建和存储可能长寿的引用和指向数组元素的指针,如

    const uint8_t *byte = &packet[3];
    
    Run Code Online (Sandbox Code Playgroud)

    如果这是不合需要的,那么按值返回也会阻止该功能.

  2. 是的,const将为非const对象调用该函数的版本(假设您没有提供非const版本).

  3. 专门为此目的引入了例外情况.例外情况为您提供了错误情况的专用反馈路径,而不会影响函数声明和规范(即,您不必为错误返回保留任何值,也不必为此目的引入任何参数).