c++非常量-常量重载方法选择



我的类中有const重载方法:

class A{
  public:
     typedef int data[10];
           data& operator[](int index);
     const data& operator[](int index) const;
}

这个类正在为它的内部数据实现写时复制。我想,既然我允许直接访问数据,我必须在每次使用operator[]时创建共享数据的副本(如果它显然是共享的),但不是operator[] const。然而,即使代码使用operator[]读取数据,但对象本身没有声明为const,它仍然会导致创建副本,因为将使用operator[]。有什么语法可以让我选择调用哪个操作符吗?

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

为什么操作符返回data&而不是引用单个项目的int& ?

话虽如此,你的选择包括:

  • 即使不需要,也要拷贝。
  • 读取或写入使用操作符,另一个使用命名方法(例如GetRef)。
  • 在使用点将对象强制转换为const: static_cast<const A&>(obj)[index]

您需要创建一个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;

}

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

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

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

如果要实现写时复制,则根本不应该定义那些订阅操作符。调用对象x的订阅方法的const版本的客户端不允许随后使用该引用来修改x的组件,但该引用仍应反映其他客户端对x(该组件)所做的更改。但这种情况不会发生在写时复制策略中,因为更改将发生在与引用点不同的副本上。

两个客户端调用具有相同索引的非const订阅操作符,应该获得对相同 data对象的(可修改的)引用;但是它们不会,因为在调用订阅操作符时已经生成了两个独立的副本。

相反,您可以使用一个订阅方法按值返回data。这避免了为x的组件创建别名的错觉(正如我所说的,在实现写时复制时必须是错觉)。您还可以提供一个方法来修改x的组件(而不是将此操作拆分为一个订阅,然后对所获得的引用赋值),该方法可以在内部创建一个副本,或者在已经创建副本的情况下直接修改组件。这将对客户端隐藏写时复制实现的使用。

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

最新更新