gpt4 book ai didi

c++ - 定义非常量 'get' 成员函数的原因?

转载 作者:IT老高 更新时间:2023-10-28 21:46:22 25 4
gpt4 key购买 nike

我正在通过 Stroustrup 的(使用 C++ 的编程原理和实践)一书学习 C++。在练习中,我们定义了一个简单的结构:

template<typename T>
struct S {
explicit S(T v):val{v} { };

T& get();
const T& get() const;

void set(T v);
void read_val(T& v);

T& operator=(const T& t); // deep copy assignment

private:
T val;
};

然后要求我们定义一个 const 和一个非 const 成员函数来获取 val

我想知道:在任何情况下,有非 const get 函数返回 val 有意义吗?

在我看来,我们不能在这种情况下间接地改变值(value)。哪些用例需要 const 和非 const get 函数来返回成员变量?

最佳答案

非常量 setter/getter ?

Getter 和 setter 只是约定俗成的。有时使用的习惯用法不是提供 getter 和 setter,而是提供类似于

struct foo {
int val() const { return val_; }
int& val() { return val_; }
private:
int val_;
};

这样,根据实例的常量,您可以获得引用或拷贝:

void bar(const foo& a, foo& b) {
auto x = a.val(); // calls the const method returning an int
b.val() = x; // calls the non-const method returning an int&
};

这是否是一般的好风格是一个见仁见智的问题。在某些情况下,它会导致混淆,而在其他情况下,这种行为正是您所期望的(见下文)。

无论如何,更重要的是根据类应该做什么以及你想如何使用它来设计一个类的接口(interface),而不是盲目地遵循关于 setter 和 getter 的约定(例如,你应该给方法一个有意义的名称,它表达了它的作用,而不仅仅是“假装被封装,现在让我通过 getter 访问你所有的内部结构”,这就是在任何地方使用 getter 的实际含义)。

具体例子

考虑到容器中的元素访问通常是这样实现的。作为一个玩具示例:

struct my_array {
int operator[](unsigned i) const { return data[i]; }
int& operator[](unsigned i) { return data[i]; }
private:
int data[10];
};

向用户隐藏元素并不是容器的工作(甚至 data 也可能是公开的)。您不希望根据是否要读取或写入元素来访问元素的不同方法,因此在这种情况下提供 const 和非常量重载非常有意义。

来自 get vs encapsulation 的非 const 引用

也许不是那么明显,但是提供 getter 和 setter 是支持封装还是相反,这有点争议。虽然一般来说,这个问题在很大程度上是基于意见的,但对于返回非 const 引用的 getter,它与意见无关。他们确实打破了封装。考虑

struct broken {
void set(int x) {
counter++;
val = x;
}
int& get() { return x; }
int get() const { return x; }
private:
int counter = 0;
int value = 0;
};

顾名思义,此类已损坏。客户端可以简单地获取一个引用,并且类没有机会计算值被修改的次数(正如 set 所建议的那样)。一旦您返回一个非常量引用,那么关于封装,将成员公开几乎没有什么区别。因此,这仅用于此类行为是自然的情况(例如容器)。

附言

请注意,您的示例返回的是 const T& 而不是值。这对于模板代码是合理的,因为您不知道拷贝的成本,而对于 int 您不会通过返回 const int& 而不是 整数。为了清楚起见,我使用了非模板示例,但对于模板代码,您可能宁愿返回 const T&

关于c++ - 定义非常量 'get' 成员函数的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53683047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com