[英]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.