一个const成员函数,返回一个指向非const成员变量的指针,为什么它是好的
a const member function, returning a pointer to a non const member variable, why would it be good?
我在一个大型团队中工作(大多数是非专业程序员,我是其中之一)。我经常看到下面的例子
void T::DoChanges(I i); // will make changes to internal structure of T (non-const)
V T::GetValue();
class A
{
private:
T* fMember;
public:
A();
T* GetMember() const {return fMember;}
}
,其中用例将是
A a;
I i;
a->GetMember()->DoChanges(i);
V v = a->GetMember()->GetValue();
这种做法违反了我在学习编程课程时学到的一个原则,即const不仅指类实例的位结构,还指内部逻辑结构。在这种理念下,成员函数应该采用以下形式:
T* GetMember() {return fMember;}
const T* GetMember() const {return fMember;}
我听说有些人认为const应该只引用成员,严格地用c++术语来说。为什么有人会赞成这种做法?
创建成员函数向该函数的用户表明,它不会修改任何类成员。
返回的成员可以是也可以不是const
,但是将成员函数设置为const可以让类的用户清楚地知道函数的行为。
这在很大程度上取决于设计,但对于您的情况,我不明白为什么需要两个原型。
你需要问自己的问题是,你是否希望人们通过get
来改变你的T
成员。
如果你这样做了,你的原型应该是这样的:
T* GetMember() const {return fMember;}
如果没有,则将返回值设为const:
const T* GetMember() const {return fMember;}
函数不一定是const
,但考虑到它可以没有问题。话虽如此,您会在不同的非const成员函数中调用该函数吗?因为如果你打算这样做,它不会工作,因为它不是const
。
因为你只返回一个指向成员的指针,而实际上没有改变任何东西,我将使函数const
。这也可以作为一个指示,指示其他在项目上工作的人,该函数不会在内部修改任何东西。
返回值是否应该是const
完全取决于设计。
我要回答说,这是一个设计问题,你是否喜欢可变访问器(在这种情况下,你选择第一个const
版本),或者如果你想禁止常数引用来修改指针(在这种情况下,你选择第二个,两个重载版本)。
但是仔细想想,我认为你的问题表明getter和setter通常是一个坏主意。您不应该盲目地转发类成员(在这种情况下,您不妨将它们设置为公共成员)。相反,您的类应该提供一个抽象实现的有意义的接口。因此,理想情况下,在你的类中有一个原始指针这一事实永远不应该引起用户的关注,而你的接口函数会负责做出相关的逻辑一致性保证。
如果您选择放弃这些OO设计原则,那么我认为您只能靠自己了,您应该做最适合您整体设计的任何事情。
可以说,类的逻辑结构与您对所指向的内容所做的更改无关。例如,考虑一个链表节点。只要下一个(也可能是前一个)指针相同,节点就是常量——但是节点并不关心您是否更改了下一个节点。此外,T本身在设计上可能只是一个不可变对象,因此const T
是一个没有意义的区别。
这非常好,并且在与T* const
相同的情况下非常有用。
考虑从多个线程访问哈希表。当另一个线程访问对象时,内部结构不需要改变,但这并不意味着哈希表只需要包含const指针。(锁定单个对象比锁定整个数据结构更具可扩展性。)
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- C++ - 如何在结构向量中找到结构体一个成员的最大值?
- 无法将指向类的成员函数的函数指针作为参数传递给同一类的另一个成员函数
- 使用只有一个成员的工会的目的是什么?
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- std::mutex作为一个成员变量对多个线程来说是安全的吗
- 使用线程从另一个成员函数调用一个Member函数
- 如何通过指针将模板成员函数传递给另一个成员函数
- 只有一个成员的匿名联盟
- 复制一个对象并使两者共享一个成员变量 (C++)
- 初始化指针或引用成员变量以指向另一个成员
- 在另一个成员函数中调用成员函数时'int'之前的预期主表达式
- C 将成员函数作为参数传递给另一个成员函数
- 将结构编写为二进制,其中一个成员是字符串
- 如何在另一个成员函数中修改具有常量返回类型的成员函数的返回值
- 从其后声明的另一个成员数据初始化成员数据是否为未定义行为
- 如何使一个成员变量等于在main()中设置的另一个成员变量
- 在另一个成员中动态添加类成员
- 在对结构数组的一个成员进行排序后,移动其成员的其余部分
- 将类成员函数作为参数从同一类的另一个成员函数传递