这种问题很有意思。
我们都知道派生类对象可以访问基类的属性, 因为是继承(共有),继承基类的属性并在此基础上做扩充。
因此支持派生类对象、指针、引用赋给基类对象, 也叫切片操作、也叫上行转化。
但是基类不能赋给派生类对象, 是不支持的。 你可以强转基类对象为派生类对象指针,进行赋值, 这种操作也叫下行转化,存在安全隐患。
那么如何让基类访问派生类对象独有的属性呢?
1、我想我们应该想想看多态, 这是我第一次想到这个问题的联想。 多态允许我们基类对象访问派生类重写的虚函数, 但是这是要存放在虚表中 的虚函数,且完成重写才可以。
2、第二点, 我们都知道一个对象实例化,当它去访问它的属性时,是通过this指针实现的,如果我们能让基类获取派生的对象的this指针, 不就可以访问派生类的属性了嘛。。。
基于这两点,我想思路已经很明显了, this指针很关键, 多态的目的是让派生类重写虚函数时返回自己的this指针, 这样我们基类对象就可以访问了。
基于原理我们写一段代码作为测试:
#include<iostream> using namespace std; //声明 class child; class Base { public: virtual child* Point() { cout << "不支持操作!" << endl; //return *(child*)nullptr; //将nullptr转化为child指针类型, 然后解引用。 return nullptr; } }; class child : public Base { public: //虚函数重写 virtual child* Point() { return this; } //测试函数1 void FUN1() { cout << "hello, i am fun1!!" << endl; } private: //测试函数2 void FUN2() { cout << "hello, i am private fun2" << endl; } }; int main() { Base* b = new child; b->Point()->FUN1(); // b->Point()->FUN2(); //不可以访问,就像类外无法访问类内私有属性 return 0; }测试结果:
hello, i am fun1!!
上面的FUN1函数和FUN2函数是派生类对象独有的。
基类调用重写后的虚函数的返回值(也就是派生类对象this指针)然后访问到了派生类的成员函数FUN1, 但是不能访问私有成员函数FUN2。
还有其他方法
#include <iostream> using namespace std; template<class T> class Base { public: Base() { T* child_point = (T*)this; child_point->FUN1(); } }; class child : public Base<child> { public: void FUN1() { cout << "hello, i am FUN1!!" << endl; } private: void FUN2() { cout << "hello, i am private FUN2!!" << endl; } }; int main() { child ch; return 0; }利用模板类使用,但是感觉这种使用方式不方便。
实例化派生类对象, 利用构造期间调用基类的构造函数,在基类的区域内短暂调用了派生类的属性, 当回到派生类的区域,就gg了。 没有第一种稳定长久。