类的只读和只写版本的语义

C++: Semantics for read-only and write-only versions of a class

本文关键字:版本 语义 只读      更新时间:2023-10-16

在我的程序中,我有一个名为Foo的数据结构。程序的一部分从一组参数构造Foo,因此需要访问可变方法。程序的另一部分将只从Foo读取,因此不应该访问可变方法。

实现这一点的最佳方法是什么,还是我对类应该如何工作的看法是错误的?我以前用过这种方法:

class FooR {
public:
    int read() { return x; }
protected:
    int x;
};
class FooRW : public FooR {
    void mutate(int nx) { x = nx; }
};

但是这种方式感觉像是在滥用继承,而且我认为在程序的两个部分有两个非常相似的命名类可能会引起混淆。有更好的方法吗?你能用一些巧妙的方法使用const吗?

编辑:

@jens指出,在程序的只读部分使用const引用应该可以工作,这使我意识到知道我的数据结构实际上是一个树是很重要的,就像:

class Foo {
public:
    void splitNode();
    Foo *getChild(int n) const; // const Foo?
private:
    Foo *children[2];
};

是否有一种方法可以强制const Foo只返回const对其子节点的引用?

程序中不需要更改对象的部分应该只使用const引用,并将非可变成员函数标记为const。

class FooR {
public:
    int read() const { return x; }
    void mutate(int nx) { x = nx; }
private:
    int x;
};
void f1(FooR const& obj)
{
    int x = obj.read();
    // cannot use obj.mutate(x+1);
}
void mutatingFunction(FooR&);

您可以在工厂或构建中进行构造,并返回std::unique_ptr<FooR const>std::shared_ptr<FooR const>以防止其他人使用变化的接口。

同样的方法也适用于树。声明一个返回Foo const*的const重载和一个返回非const指针的非const重载。后者不能在const引用中使用。

class Foo {
public:
    void splitNode();
    Foo const* getChild(int n) const;
    Foo* getChild(int n); 
private:
    Foo *children[2];
};