我目前正在努力学习自己的C ++,而作为一名C#-enthusiast,我总是喜欢使用getter和setter。但是,我对C ++中的用法有点不确定。
对于我的示例,我想使用MVC设计模式在C ++中创建Todo-List应用程序。对于我的条目,我想使用一个std::vector
来保存Container类,其中包含条目的所有相关值。
目前,此向量存储在我的模型中。当我点击我的按钮时,我现在将调用重定向到一个确定调用的方法,并调用EventHandler类中的方法。此调用包含UI之外的所需数据,现在我还想从模型中获取矢量,因此我可以将其作为参考传递给EventHandler。
现在,我正在使用一个getter,它从成员向量中获取引用,如下所示:
部首:
public:
std::vector<TodoEntry>& getTodoEntries();
private:
std::vector<TodoEntry> m_todoEntries;
.cpp的:
std::vector<TodoEntry>& UIModel::getTodoEntries()
{
return m_todoEntries;
}
这是在C ++中执行此操作的正确方法吗?我不太确定,所以我宁愿在这里问。
答案 0 :(得分:6)
在C ++中通常使用getter和setter,并且在许多情况下允许在实现可以更改时提供稳定的接口。
在某些情况下,在getter中返回引用可能有意义,但通常,您应该更喜欢通过复制返回。原因是您通常希望getter是const
方法(处理const
个对象并保证对象不被修改)。
但是,如果返回非const引用或指向内部的指针,则表示即使getter是const
方法,调用者也可以修改对象。 (即使使用const
引用,调用者也可const_cast
,但他打破了类型系统,因此您可以让他对后果负责。此外,对象通常拥有返回的引用或指针指向的对象,并且调用者必须小心其生命周期以避免悬空指针。
当然,就性能而言,返回潜在的大vector
个潜在大对象可能会非常广泛:它会复制vector
。 vector
的复制构造函数将复制它包含的所有TodoEntry
个对象。它的作用完全取决于TodoEntry
的复制构造函数,但通常它会复制它包含的所有东西(a.k.a深拷贝)。
所以这可能是最后返回引用的情况。也许你可以在这里返回const
参考?这是我的偏好,有这个签名:
const std::vector<TodoEntry>& getTodoEntries() const;
经常,我建议Scott Meyer的书 Effective C++ 在第28项中处理这个问题:避免返回&#34;句柄&#34;对象内部。
答案 1 :(得分:1)
纯粹的制定者/吸气者不会给你任何东西,只是为了更多打字。他们也更难以间接访问类成员(通过指针),并且你没有得到任何回报。不要做纯粹的二传手/吸气鬼。
当getters 与setter配对时(底层数据成员为const
并且在初始化期间仅设置一次或从类状态派生的值),或者提供某些不变的检查。
Setters也可以在提供不变检查时使用。我从来没有买过这个论点&#34;是的,现在没有不变的检查,但我可能会在以后添加#34;。添加时,比引入setter要多。我已经看到了一个10年以上的代码库,在这个假装下引入了setter,并且从未进行过不变检查。