C++ Getter vs public成员以及替换返回对象的可能性
我最近与一位同事就getter&setter进行了一场辩论,getter&setter使用指针来对抗公共成员指针(该主题导致了同样的辩论,没有指针,而是让getter返回引用)。我不确定这个话题是否会重复,但在寻找这个话题的答案时,我发现只有三个话题(,和)与“getter/setters vs public member”这个话题相关,但没有指出我们辩论的方向 因此,情况如下:C++ Getter vs public成员以及替换返回对象的可能性,c++,pointers,getter-setter,C++,Pointers,Getter Setter,我最近与一位同事就getter&setter进行了一场辩论,getter&setter使用指针来对抗公共成员指针(该主题导致了同样的辩论,没有指针,而是让getter返回引用)。我不确定这个话题是否会重复,但在寻找这个话题的答案时,我发现只有三个话题(,和)与“getter/setters vs public member”这个话题相关,但没有指出我们辩论的方向 因此,情况如下: //example for TextProperties class TextProperties { protec
//example for TextProperties
class TextProperties
{
protected:
int m_size;
bool m_bold;
public:
bool Bold() { return this->m_bold; }
void Bold(bool bold) { this->m_bold = bold; }
int Size() { return this->m_size; }
void Size(int size) { this->m_size = size; }
TextProperties()
{
this->m_bold = false;
this->m_size = 5;
}
~TextProperties() {}
}
//example for Text
class Text
{
protected:
TextProperties* m_properties;
public:
TextProperties* Properties() { return this->m_properties; }
void Properties(TextProperties* properties) { this->m_properties = properties; }
Text()
{
this->m_properties = new TextProperties();
}
~Text()
{
delete this->m_properties;
}
}
//the usage as I want it:
int main()
{
Text* exampleText = new Text();
//easily and short a property gets changed
exampleText->Properties()->Bold(true);
delete exampleText;
}
有一个类Text
。Text
类型的对象始终包含另一个TextProperties
类型的对象(例如大小、颜色、粗体、斜体、下划线等)。要修改属性,我想直接使用TextProperties
-对象的方法,而无需创建新对象。这最终导致getter返回TextProperties
-对象的指针
下面是一个非常简单的例子:
//example for TextProperties
class TextProperties
{
protected:
int m_size;
bool m_bold;
public:
bool Bold() { return this->m_bold; }
void Bold(bool bold) { this->m_bold = bold; }
int Size() { return this->m_size; }
void Size(int size) { this->m_size = size; }
TextProperties()
{
this->m_bold = false;
this->m_size = 5;
}
~TextProperties() {}
}
//example for Text
class Text
{
protected:
TextProperties* m_properties;
public:
TextProperties* Properties() { return this->m_properties; }
void Properties(TextProperties* properties) { this->m_properties = properties; }
Text()
{
this->m_properties = new TextProperties();
}
~Text()
{
delete this->m_properties;
}
}
//the usage as I want it:
int main()
{
Text* exampleText = new Text();
//easily and short a property gets changed
exampleText->Properties()->Bold(true);
delete exampleText;
}
我的同事反对这种解决方案,因为使用这种解决方案,可以在绕过任何setter的同时打开门来替换对象(在使用引用返回getter时也是如此)
//An example for the replacing bypassing the setter:
int main()
{
Text* exampleText = new Text();
//easily and short a property gets changed
exampleText->Properties()->Bold(true);
TextProperties* test = exampleText->Properties();
*test = *(new TextProperties());
//at this point the text wouldn't be bold
delete exampleText;
}
据我所知,唯一可能安全的解决方案(对象不能被另一个对象替换)是返回const
,并强制使用该类的任何人创建一个新的TextProperties
-对象以仅更改一个属性。如前所述,这种解决方案是不可取的
//just as intimation how the other, replacing safe
//way of usage I want to avoid could look:
int main()
{
Text* exampleText = new Text();
//if needed copy-construct the object otherwise just use (default) constructor
TextProperties* newProperties = new TextProperties(exampleText->Properties());
newProperties->Bold(true);
exampeText->Properties(newProperties);
delete exampleText;
}
到目前为止的情况-现在的辩论:
接受能够直接修改属性的目标我的同事than提到,他认为解决方案对公众成员没有区别。我的观点如下:
- 使用getter/setter可以隐藏内部(=封装)
- 内部更改可以更容易/更快地执行,因为公共成员访问分散在所有源代码中
- 也可能是带有前缀和/或后缀的难看的内部名称被一个漂亮且易于描述的名称覆盖(例如,内部:int m_x,m_y外部:Width(),Height()(是的,人们会这样做))使使用类的代码更清晰、更容易理解
- 通过提供getter/setter,类使用者可以确保以应该的方式完成任务(对于我来说,只有public member对于int等简单类型才有意义。因为更复杂的对象可能需要一些特定的操作,例如确保所包含信息的正确性)此外,该构件还受到保护,防止因错误而进行修改
- 如果有人想在绕过getter的同时替换对象,他必须故意这样做,因此当代码不能按预期工作时,这是他的错,此时我的任务只包括确保不会发生损坏(但这始终是我的任务)->如果你想强制执行某些事情,你可以执行。。。好或坏这是另一个问题,C++没有处理,它只是给出了可能性;李>
- 避免按值复制时,不需要复制对象,这可以但不一定是性能增益(通过编辑添加的点)
- 当以可编辑的方式访问对象并直接更改所访问对象的成员时,它(对我来说)较短且易于理解的源代码(通过编辑添加的点)
如果已经决定使用getter和setter,并且使用引用或指针破坏了getter的封装:为什么这仍然比使成员成为公共成员更好?(我试图提供拥有这些getter的列表参数,我想知道这些参数中哪些是in/valid,哪些是pro/contra,这些getter或public成员)
希望这不是重复,我期待一些有趣的答案。谢谢!:) 返回指向私有成员的指针或引用的一些潜在问题:
- 正如您所提到的,封装被破坏了。您已直接授予该成员访问权限,尽管它是私有的
- 如果
类在其Text
成员上保留一些不变量,则这些不变量可能会通过从类外部修改对象而失效TextProperties
- 客户机代码必须知道,只有当返回该引用的
对象仍处于活动状态时,该引用才有效文本
std::vector
是一个容器,因此operator[]
将公开其中包含的元素(就像在数组上使用[]
一样)。相反,您正在公开文本的某些状态