繁体   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