[英]In has-a relation is it a good design, to access and alter the private members of contained class directly from the Parent class method
考虑这个例子:
class Child
{
private:
string m_Name;
public:
string* GetNameAccess()
{
return &m_Name;
}
};
class Parent
{
private:
Child m_Child;
public:
void DoSomething()
{
string *pChildName = m_Child.GetNameAccess(); // Is this the right thing to do?
*pChildName = "NewName";
}
};
在has-relation 中,我们知道Parent 对象拥有子对象(即控制子对象的生命周期)。 那么 Parent 是否允许直接访问 child 的私有成员并更改它们?
尽管有一个返回指向私有数据成员的指针的公共函数在 C++ 中是合法的,但它破坏了封装的全部要点。 如评论中所述,如果您想提供对数据成员的这种“直接”访问,则只需将其公开即可。
但是数据成员应该是私有的有很多很好的理由——例如提供一些控制该成员允许或禁止哪些值。 在这种情况下,您应该提供真正的“getter”和“setter”函数,以允许从类外部对私有成员进行受控访问。 “getter”不应允许修改数据(因此返回const&
引用通常是合适的),“setter”应在修改数据之前对其给出的值执行所需的检查。
这是一个非常简短的大纲,说明了这样的“getter”和“setter”如何寻找您的示例:
#include <string>
class Child {
private:
std::string m_Name;
public:
const std::string& GetName() { // The "const" prevents modification with the getter
return m_Name;
}
void SetName(const std::string& name) {
// A real setter allows error checking ...
if (name != "Attila the Hun") m_Name = name;
}
};
class Parent {
private:
Child m_Child;
public:
void DoSomething() {
std::string temp = m_Child.GetName();
if (temp.empty()) temp = "New Name";
else temp += " (Modified)";
m_Child.SetName(temp);
}
};
这个简短的片段演示了如何防止父母将他们的孩子命名为“Attila the Hun”,这可能是实现 setter 函数的合理预防措施。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.