【问题标题】:In C++ is it possible to access a 1st derived object's protected base data member from a sibling 2nd derived object?在 C++ 中,是否可以从同级的第二个派生对象访问第一个派生对象的受保护基础数据成员?
【发布时间】:2023-04-10 20:22:01
【问题描述】:

我正在编写一个 C++ 程序,其中我有两个来自基类的派生对象,例如 Derived_1 和 Derived_2。

在处理过程中,第一个对象调整基础数据成员(这里只是模拟使用 Derived_1 的默认构造函数)。然后我想做的是从 Derived_1 对象中读取该数据,并在 Derived_2 的构造函数中使用它来初始化 Derived_2 中的相同成员。

// -std=c++14
#include <iostream>

class Base {
 public:
  int data(void) { return data_; }

 protected:
  int data_{0};
};

class Derived_1 : public Base {
 public:
  Derived_1(void) { this->data_ = 42; }
};

class Derived_2 : public Base {
 public:
   // Derived_2(const Derived_1& a1) { this->data_ = a1.data_; }
};

int main() {
  Derived_1 a1;
  std::cout << "Derived_1 data: " << a1.data() << '\n';

  // Derived_2 a2 = a1;
  // std::cout << "Derived_2 data: " << a2.data() << '\n';
}

如果Derived_2中的构造函数没有注释,就会出现这个错误:

In constructor ‘Derived_2::Derived_2(const Derived_1&)’:
error: ‘int Base::data_’ is protected within this context
Derived_2(const Derived_1& a1) { this->data_ = a1.data_; }
                                                  ^~~~~

我在这里查看了一些关于 SO 试图找到解决方案的相关问题,(例如) Access a derived private member function from a base class pointer to a derived objectWhy can I access a derived private member function via a base class pointer to a derived object? 但如果我看到了答案,我目前很难找到答案。可能只是我的经验不足。

感谢您帮我解决这个问题。

【问题讨论】:

  • 您无法访问其他类型的受保护成员,只能访问您自己的类型。
  • 感谢 Tavian 的回复。
  • Derived_2(const Derived_1&amp;) 不是复制构造函数。
  • @aschepler 感谢您指出这一点。
  • @aschepler 问题已编辑以反映您的观点,谢谢。

标签: c++ c++11 inheritance


【解决方案1】:

是的,可以通过将Derived_2 设为friend of Derived_1

class Derived_1 : public Base {
    //This says that Derived_2 is a friend, which means that Derived_2
    //can access every member in Derived_1
    friend class Derived_2;
public:
    Derived_1(void) { this->data_ = 42; }
};

所以现在你可以这样做了:

class Derived_2 : public Base {
public:
     Derived_2(const Derived_1& a1)
     { 
         //Legal, Derived_2 is a friend of Derived_1, so it can access the
         //protected member 'data_'
         this->data_ = a1.data_; 
     }
};

请注意,现在Derived_2 可以修改Derived_1每个数据成员,而不仅仅是data_

【讨论】:

  • 感谢 Rakete1111,这就是解决方案。我本能地认为 friend 可能是答案,但我的尝试很笨拙并且没有成功。我也很欣赏你回答中的好 cmets!
【解决方案2】:

第一个错误是基类中声明的data_,派生类无法访问使用。要解决此问题,您需要包含这是您的派生类:

using Base::data_;

现在,OOP 建议每个对象都有与之关联的定义明确的方法,并且没有变量可以直接访问。你可以这样做:

class Derived_2 : public Base {
 public:
   Derived_2(const int& a1) { this->data_ = a1; }
};

并像这样使用它:

Derived_2 a2(a1.data());

或者您可以将Derived_2 声明为Derived_1 的朋友,就像@Rakete1111 在他的回答中提到的那样:

class Derived_1 : public Base {
//This says that Derived_2 is a friend, which means that Derived_2
//can access every member in Derived_1
friend class Derived_2;
public:
    Derived_1(void) { this->data_ = 42; }
};

但是,如果您这样做,Derived_1 中的所有变量都可以直接由Derived_2 访问。

EDIT 1(按要求):类的用法:

版本 1:

class Derived_1 : public Base {
 using Base::data_;
 public:
  Derived_1(void) { this->data_ = 42; }
};

class Derived_2 : public Base {
 using Base::data_; 
 public:
    Derived_2(const Derived_1& a1) { this->data_ = a1.data(); }
};

版本 2:

//Declaration of Derived_2 here for Derived_1 
//to know that a class with such a name exists
class Derived_2 : public Base;

class Derived_1 : public Base {
 using Base::data_;
 friend class Derived_2;
 public:
  Derived_1(void) { this->data_ = 42; }
};

class Derived_2 : public Base {
 using Base::data_; 
 public:
    Derived_2(const Derived_1& a1) { this->data_ = a1.data_; }
};

【讨论】:

  • 感谢您的回答。您提到要解决此问题,您需要包含using Base::data_; i[n] 您的派生类,我玩过它但无法有所作为。和以前一样,这可能只是我由于缺乏经验而犯的一个笨拙的错误。您是否可以编辑您的答案以准确演示如何在两个派生类中使用它?另外,特别感谢您提供有关良好 OOP 使用的提示。在我的使用代码中,Derived_2 a2 = a1; 似乎比 Derived_2 a2(a1.data()); 更直接地传达了我的意图,但是是的,好建议!
  • @Sahil_Arora 感谢 Sahil 的澄清,非常感谢!
【解决方案3】:

派生类只能访问它们自己的基类子对象的受保护成员。他们无权访问其他类的基类受保护成员,即使该基类与其自己的类型相同。

可能的解决方案:

  • 声明Base::data_ public。
  • 或者将Derived_2声明为Derived_1的朋友。

【讨论】:

  • 谢谢 user2079303。我特别不想 想做的一件事是在我的基类中公开数据。是的,朋友原来是答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-27
  • 2016-04-07
  • 2014-08-27
  • 2010-09-25
  • 1970-01-01
  • 2018-11-27
相关资源
最近更新 更多