【问题标题】:How to make a derived class access the private member data?如何让派生类访问私有成员数据?
【发布时间】:2013-09-22 13:38:40
【问题描述】:

我遇到了一个 C++ 问题。我有一个基类,它在类的私有可见区域内有一个自引用对象指针。我在基类中有一个构造函数来初始化这两个指针。现在我有我的派生类,它的访问说明符是私有的(我想让我的基类的公共成员函数私有)。现在通过我的派生类的成员函数,我想创建一个对象指针,它可以指向基类的私有数据,即那些自引用对象指针。我的代码是:

class base{
private:
     base *ptr1;
     int data;
public:
     base(){}
     base(int d) { data=d }
};

class derived:private base{
public:
     void member()
};

void derived::member()
{
base *temp=new base(val); //val is some integer
temp->ptr1=NULL; //I can't make this happen. To do this I had to declare all the
                 //private members of the base class public. 
}

【问题讨论】:

  • 使用protected 而不是private ?
  • private 成员创建protected getter?但是,如果您需要这样的解决方案,通常您的设计就有缺陷。
  • 那也行不通。编译器错误。也试过了。只有将其公开,我才能访问它。但这会使代码易受攻击。
  • protected 是您所需要的(这就是 protected 的用途)。如果出现错误,还有其他问题。如果您希望人们更好地理解您的问题,请发布SSCCE 和错误。
  • 不幸的是,这个问题是有缺陷的。您可能认为您想要或需要这样做;但你没有。不仅没有必要,而且有害。 class 使用private 属性进行封装;封装反过来意味着类可以维护其属性的不变量,并且状态的精确表示是隐藏以避免意外依赖。打破封装,你会打开一罐讨厌的蠕虫。

标签: c++


【解决方案1】:

派生类不能访问其基类的私有成员。没有任何类型的继承允许访问私有成员。

但是,如果您使用 friend 声明,您可以这样做。

【讨论】:

  • 我知道,但没有办法做到这一点。唯一的其他选择是使用朋友类。但我想用继承来解决这个问题。
  • 您可以通过其内存地址直接访问私有成员。它实际上并不涉及继承,但它确实有效。
【解决方案2】:

除了友谊之外,没有其他方法可以访问其他班级的私人数据。然而,你可以用继承做的是访问基类的受保护数据。但这并不意味着您可以访问另一个基类型对象的受保护数据。您只能访问派生类的基础部分的受保护数据:

class base{
protected:  //protected instead of private
     base *ptr1;
     int data;
public:
     base(){}
     base(int d) { data=d; }
};

class derived:private base{
public:
     void member();
};

void derived::member()
{
    base *temp=new base(3); 
    //temp->ptr1 = 0; //you need friendship to access ptr1 in temp

    this->ptr1 = 0; // but you can access base::ptr1 while it is protected
}

int main(){}

【讨论】:

    【解决方案3】:

    尝试将protected作为基类中的访问说明符并以私有模式继承基类.....但是为了进一步使用基类的成员函数,您可能需要很少的短内联函数,因为它们也将被转换为私人的

    【讨论】:

      【解决方案4】:

      嗯,我想,你试图达到这样的结果!这不会报告任何编译器错误等。祝你好运!!!

      class base{
      private:
           base *ptr1;
           int data;
      public:
           base(){}
           base(int d) { data=d; }
           base* getPtr();   //getter to get access to base pointer
           void setPtr(base* val); // setter to set value of the pointer variable
      };
      
      base* base::getPtr()
      {
          return ptr1;
      }
      
      void base::setPtr(base* val)
      {
          ptr1 = val;
      }
      
      class derived:private base{
      private:
          base* getPtr();
          void setPtr(base* val);
      public:
           void member();
      
      };
      
      base* derived::getPtr()
      {
          return base::getPtr(); //derived version just invokes the base class version
      
      }
      
      void derived::setPtr(base* val)
      {
          base::setPtr(val);     //derived version just invokes the base class version
      
      }
      void derived::member()
      {
          base *temp=new base(5); //put in a random number here instead of val
          temp -> setPtr(nullptr);
      }
      

      【讨论】:

        【解决方案5】:

        我不同意其他一些声称访问私有成员的唯一方法是将其设为friend

        您可以通过其在内存中的地址直接访问私有成员。如果您对此感到满意,那就是。您可以在基类中有一个函数返回私有成员的地址,然后在派生类中使用一些包装函数来检索、取消引用和设置私有成员。

        【讨论】:

        • 我的答案是否因为不起作用而被否决?因为据我所知,您可以通过其在内存中的地址访问私有成员变量。非成员函数访问另一个类的私有成员没有访问冲突。这是一个解决方案,虽然有些人可能不喜欢,但它确实有效。
        • 您的答案被否决了,因为即使它有效,它也违反了面向对象编程的所有基本原则。私有、受保护和公共存在是有原因的,绕过它们会使代码不可移植、易碎、难以理解……
        • @Pietro 当我做出这个回答时,我还在上高中。从那以后我学到了很多东西。我现在明白了,不过感谢您的解释。
        猜你喜欢
        • 1970-01-01
        • 2011-08-16
        • 2018-04-19
        • 1970-01-01
        • 1970-01-01
        • 2017-08-07
        • 2021-07-01
        • 2011-08-04
        • 1970-01-01
        相关资源
        最近更新 更多