簡體   English   中英

在 has-a 關系中,直接從 Parent 類方法訪問和更改包含類的私有成員是一個好的設計嗎

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM