访问现有基对象的受保护成员
Access protected members of an existing base object
假设我有一个带有protected成员的基类:
class Base
{
public:
Base(int data)
: m_attribute(data) {}
protected:
int m_attribute;
};
和基类的派生类:
class Derived : public Base
{
public:
int get_attribute()
{
return m_attribute;
}
};
首先:我可以做这个,对吗?这完全合法吗?
如果是,那么问题是:
- 我不能改变基类中的任何东西;
- 我有一个基类对象,我需要访问它的m_attribute成员;
我应该先从这个基类对象向下转换到派生类对象,然后调用get_attribute()函数吗?像这样:
Base base(5);
Derived* derived = static_cast < Derived*>(&base);
int base_attribute = derived->get_attribute();
或者访问受保护成员的其他方法是什么?我知道好友函数是一个选项,但是我不能改变基类
我应该先从这个基类对象向下转换到派生类对象,然后调用get_attribute()函数吗?
绝对不是。基类的实例不是派生类的实例。您的转换格式错误。
这是一个有效的方法:
struct kludge : Base {
kludge(const Base& b): Base(b) {}
operator int() {
return m_attribute;
}
};
用法:
Base base(5);
int foo = kludge(base);
该组合通过复制构造派生类型的基子对象来工作。这当然取决于碱基是可复制的——你的Base
是。这很容易调整工作与移动。
作为语法糖,可隐式转换为成员的类型。如果你愿意,你可以使用getter
如果基类重载后没有默认构造函数,并且没有默认构造函数,则派生类必须使用成员初始化列表初始化基类部分,否则无法实例化派生类,编译器会抱怨基类中缺少默认构造函数:
class Base
{
public:
// Base(){} default constructor by default the compiler creates one for you unless you overload it so the next one taking one parameter will hide this one
Base(int data) // hides the default ctor so derived classes must use member-initializer list
: m_attribute(data) {}
protected:
int m_attribute;
};
class Derived : public Base
{
public:
Derived() : Base(0){} // you must use member intializer list to initialize the part Base
//Derived(int x) : Base(x){} // also ok
int get_attribute(){ return m_attribute; }
};
int main()
{
Derived dervObj;
Derived* derived = static_cast < Derived*>(&baseObj);
int base_attribute = derived->get_attribute();
cout << base_attribute << endl;
}
- 也不能将基类的地址强制转换为派生对象,但可以将基类的对象强制转换为派生对象。
所以在你的例子中写在main:
Derived* derived = static_cast < Derived*>(&baseObj); // is like writing:
char* cp = static_cast < char*>(&int); // you must convert a variable not a type
为什么要从外部访问受保护的成员??请记住,公共继承将把基类的所有成员复制到派生类中,但不是私有的。
使用友好型或者将成员数据设为公共可以从外部访问它但是它破坏了数据隐藏和封装的原则然而友好型在某些情况下是必须的并且没有其他选择那么小心使用但是将数据设为公共最好还是回到结构体
派生类可以访问和修改public
和protected
基类的属性和方法。
那么,你不能将Base分为Derived。Derived继承自Base,所以Derived是一个Base。但是基类不是派生类(Car是Vehicle, Vehicle不是Car)。
所以如果你需要一个getter,直接放到Base中,或者实例化一个Derived而不是Base。
first:
Derived* derived = static_cast < Base*>(base);
这是无效且非法的。不会编译。你不能将Base
静态转换为Base*
。
回答你的问题:
Base base(5);
Derived& derived = static_cast<Derived&>(base);
std::cout << derived.get_attribute();
或者如果你想使用指针,因为你觉得你更酷:
Base base(5);
Derived* derived = static_cast<Derived*>(&base);
std::cout << derived->get_attribute();
EDIT: static_cast
在运行时没有任何开销。它是静态的,因此它是编译时的东西。这两种方法将产生相同的结果。
- C++:无法访问声明的受保护成员
- 相同的层次结构,访问基类的受保护成员时的行为不同
- 同一模板类但模板类型的受保护成员
- 派生类无法访问基类的受保护成员
- 继承期间受保护成员的皮条
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 是否可以基于私有/受保护成员分配类枚举?
- 依赖模板基础的受保护成员
- 无法从派生类型的作用域访问另一个实例的受保护成员
- 为什么我无法使用受保护/私有继承访问派生实例中基类的受保护成员?
- 将对象强制转换为派生类以访问父类的受保护成员
- 使从一个基类派生的类能够使用继承的受保护成员
- 派生类如何使用基类的受保护成员
- 访问派生类C++中的受保护成员
- 访问基类的受保护成员
- 如何访问多个继承类中的受保护成员
- 如何从另一个类的基类访问派生类中的受保护成员
- 无法访问派生类中的基本受保护成员!(在虚函数中)
- 如何通过派生类访问基类的受保护成员?
- 如果孩子不需要父母班级的所有受保护成员,这是不好的班级设计吗?