c ++ nonconst-const-overloaded方法选择

时间:2011-04-29 13:57:42

标签: c++ const overloading

我在班上有const重载方法:

class A{
  public:
     typedef int data[10];

           data& operator[](int index);
     const data& operator[](int index) const;
}

此类正在为其内部数据实现copy-on-write。我认为,由于我允许直接访问数据,因此我必须在每次使用operator[]时创建共享数据的副本(如果它显然是共享的),而不是operator[] const。但是,即使代码使用operator []读取数据,但对象本身未声明为const,它仍将导致创建副本,因为将使用operator []。是否有任何语法可以让我选择我正在调用哪些运算符?

6 个答案:

答案 0 :(得分:2)

是:const_cast<A const&>(anAObj)[5]

答案 1 :(得分:1)

为什么运营商会返回引用单个项目的data&而不是int&

据说你的选择包括:

  • 即使结果是不需要的,也要经常复制。
  • 使用运算符进行读取或写入,并使用命名方法(例如GetRef)。
  • 在使用点将对象投射到conststatic_cast<const A&>(obj)[index]

答案 2 :(得分:1)

您需要创建一个Proxy类来替换两种方法的返回值。然后,在Proxy类中,您可以适当地处理读取和写入。这里的代码应该编译以演示这个想法(使用无符号整数数组):

typedef unsigned int UINT;

A级{

class Proxy {
public:

    Proxy(const UINT &number): _number(number) {}

    const Proxy &operator=(const Proxy &obj) {
        cout << "Writting...\n";
        _number = obj._number;
        return *this;
    }

    operator const UINT &() const {
        cout << "Reading...\n";
        return _number;
    }

private:

    UINT _number;
};

公共:

A(UINT *array): _array(array) {}

Proxy operator[](int index) {
    return _array[index];
}
const Proxy operator[](int index) const {
    return _array[index];
}

私人:

UINT *_array;

};

int main(int argc,char ** argv){

UINT myArray[] = {0, 1, 2, 3, 4};

A a(myArray);        // Normal A object

UINT num1 = a[1];    // Reading fine
a[1] = num1;         // Writting fine

const A ca(myArray); // Constant A object

UINT num2 = ca[1];   // Reading fine
ca[1] = num2;        // Writting NOT fine (compilation error)

return 0;

}

答案 3 :(得分:0)

不,除非你将引用/指针强制转换为常量。或者创建一个常量副本。

A a;
const_cast<const A &> (a)[0] /*.foo ()*/;

答案 4 :(得分:0)

实现data& at(size_t i);const data& cat(size_t);函数,因此您可以在非const对象上调用cat()来强制执行返回数据的常量。

答案 5 :(得分:0)

如果要实现copy-on-write,则根本不应定义这些订阅运算符。调用对象const的订阅方法的x版本的客户端不允许随后使用该引用来修改x的组件,但该引用仍应反映更改其他客户对x的(组成部分)做出的贡献。但是,他不会发生写入时复制策略,因为更改将发生在与参考点不同的副本中。

另外两个调用具有相同索引的非const订阅运算符的客户端应该获得(可修改的)对相同 data对象的引用;但他们不会,因为订阅操作员被调用时会有两个单独的副本。

相反,您可以使用按值返回data的订阅方法。这避免了为x组件获取别名的假象(正如我所说,当实现copy-on-write时, }。您还可以提供一个修改x组件的方法(而不是将此操作拆分为订阅,然后分配给所获得的引用),这可以在内部进行复制,或者仅修改组件这个副本已经制作好的地方。这会使客户端无法使用写时复制实现。

更一般地说,公开返回对内部对象的引用的方法,无论是否const,都暴露了这些对象存在的实现细节。这限制了以后更改实现的自由度,例如压缩数据或将数据存储在内存以外的地方。