C++是否可以从同级第二个派生对象访问第一个派生对象的受保护基础数据成员?
In C++ is it possible to access a 1st derived object's protected base data member from a sibling 2nd derived object?
我正在编写一个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的相关问题,试图找到解决方案,(例如) 从基类指针访问派生私有成员函数 指向派生对象 和 为什么可以通过指向派生对象的基类指针访问派生私有成员函数? 但是如果我看到它,我目前很难找到答案。可能只是我缺乏经验。
感谢您帮助我解决这个问题。
是的,通过使Derived_2
成为Derived_1
的friend
是可能的:
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_
第一个错误是派生类无法访问在基类中声明的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
。
编辑 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_; }
};
派生类只能访问其自己的基类子对象的受保护成员。他们无权访问其他类的基受保护成员,即使该基与其自己的基是同一类型。
可能的解决方案:
- 公开声明
Base::data_
。 - 或者宣布
Derived_2
是Derived_1
的朋友.
- 如何使用单独文件中的派生类访问友元函数对象
- 使用基类指针创建对象时,缺少派生类析构函数
- 为什么此派生对象无法访问基类的后递减方法?
- 将带有派生模板的对象传递给接受具有基本模板的对象的功能
- 放置派生C++的新基子对象
- 在 C++ 中将对象转换为派生类型
- 链表包含 c++ 中不同的派生类对象
- 如何在不使用指针的情况下将派生类的对象作为参数传递给基类中的函数?
- 如何在新的派生对象中获取基本对象的数据?
- 如何将成员函数作为参数传递并在派生对象上执行方法列表
- 获取我的基类以递增派生类对象整数
- 派生类中的对象
- 在没有默认构造函数的情况下创建的派生对象
- OOP 标识派生对象
- 如何创建派生对象的向量?
- 按基类对象访问派生类资源时出错
- 将基类分配给派生对象,反之亦然,以C++以及静态和动态对象之间的差异
- static_cast将此对象派生到C++中的基类
- 如何在构造函数完成后立即销毁从 QWindow 对象派生的内容
- 我可以判断std::type_info对象是否等于另一个对象或从另一个对象派生的类吗?