简体   繁体   English

在C ++中,是否可以从同级第二个派生对象访问第一个派生对象的受保护基础数据成员?

[英]In C++ is it possible to access a 1st derived object's protected base data member from a sibling 2nd derived object?

I'm writing a C++ program where I have two derived objects from a base class, say, Derived_1 & Derived_2. 我正在编写一个C ++程序,其中有两个来自基类的派生对象,例如Derived_1和Derived_2。

During processing, the first object adjusts the base data member (just simulating that using the Derived_1's default constructor here). 在处理过程中,第一个对象将调整基础数据成员(此处仅使用Derived_1的默认构造函数对其进行仿真)。 What I'd like to do is then read that data from the Derived_1 object and use it during Derived_2's constructor to initialize that same member in Derived_2. 然后,我想从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';
}

If the constructor in Derived_2 is uncommented, this error occurs: 如果未注释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_; }
                                                  ^~~~~

I've looked through a number of related questions here on SO trying to find a solution, (for example) Access a derived private member function from a base class pointer to a derived object and Why can I access a derived private member function via a base class pointer to a derived object? 我在SO上浏览了许多相关问题,试图找到解决方案,(例如) 从基类指针到派生对象 访问派生的私有成员函数为什么我可以通过A访问派生的私有成员函数。基类指向派生对象的指针? but I'm currently having real difficulty spotting the answer if I've seen it. 但是如果我看到了答案,我目前很难找到答案。 Probably just my inexperience. 可能只是我的经验不足。

Thanks for helping clear this up for me. 感谢您帮助我解决此问题。

Yes, it is possible, by making Derived_2 a friend of Derived_1 : 是的,可以通过将Derived_2成为Derived_2friendDerived_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; }
};

So now you can do this: 现在,您可以执行以下操作:

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_; 
     }
};

Note that now, Derived_2 can modify every data member of Derived_1 , not just data_ 需要注意的是,现在, Derived_2可以修改的每一个数据成员Derived_1 ,不只是data_

The first error is that data_ declared in the base class is not accessible to the derived classes for usage. 第一个错误是派生类无法访问在基类中声明的data_进行使用。 To fix this, you need to include this is your derived class: 要解决此问题,您需要包括以下这是您的派生类:

using Base::data_;

Now, what OOP recommends is that every object has well defined methods associated to it, and no variable is directly accessible. 现在,OOP建议的是,每个对象都有与之关联的定义明确的方法,并且没有变量可以直接访问。 You can either do: 您可以执行以下操作:

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

and use it like this: 并像这样使用它:

Derived_2 a2(a1.data());

Or you may declare Derived_2 as a friend of Derived_1 , just as @Rakete1111 mentioned in his answer: 或者,你可以声明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; }
};

However, if you do this, all the variable in Derived_1 will be directly accessible to Derived_2 . 但是,如果执行此操作,则Derived_1将直接访问Derived_2所有变量。

EDIT 1(as requested): The usage of the class: 编辑1(根据要求):该类的用法:

Version 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(); }
};

Version 2: 版本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_; }
};

Derived classes have access only to protected members of their own base class sub object. 派生类只能访问其自己的基类子对象的受保护成员。 They don't have access to other classes' bases protected members, even if that base is the same type as its own. 他们无权访问其他类的受基础保护的成员,即使该基础与其自身的类型相同。

Possible solutions: 可能的解决方案:

  • Declare Base::data_ public. 声明Base::data_ public。
  • Or declare Derived_2 as a friend of Derived_1 . 或宣布Derived_2作为朋友Derived_1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c ++继承:与派生对象的基本成员访问混淆 - c++ inheritance : confused with base member access from derived object C ++ protected:无法从派生类中访问base的受保护成员 - C++ protected: fail to access base's protected member from within derived class 基类可以访问 C++ 中的派生类受保护成员吗? - Can a base class access a derived class protected member in c++? C ++:在另一个派生类的对象的基本指针上调用(派生的)成员函数 - C++: call (derived's) member function on base pointer of a different derived class's object C ++使用派生类的对象访问基类的受保护成员函数 - C++ accessing protected member function of Base class with an object of Derived class C ++:无法从派生类访问受保护的成员 - C++: cannot access protected member from derived class C++ 从基类指针访问派生类成员 - C++ Access derived class member from base class pointer 在c ++中派生对象和基础对象之间有什么区别? - What's the difference between a derived object and a base object in c++? C ++:在不同类的派生对象的基本指针上调用静态成员函数 - C++: call static member function on base pointer of different class's derived object 从基础 object 转换为 C++ 中的派生 object - Convert from a Base object to a Derived object in C++
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM