问题描述
而我的代码是印发错误的,为什么?
///////////////// .h#ifndef HI_H_INCLUDED#define HI_H_INCLUDED#include <iostream>using namespace std;class Worker{ string name;public: Worker(string na):name(na){}private:void data() {cout<<'worker'<<endl; }};class Waiter:virtual public Worker{public: Waiter(string na1):Worker(na1){} void show() {((Worker &)*this).data(); ///强制转化为基类,为什么还是不能调用私有函数data()data(); }private: void data() {cout<<'waiter'<<endl; }};#endif // HI_H_INCLUDED//////////// .cpp#include <iostream>#include 'hi.h'#include<stdlib.h>using namespace std;int main(){ Worker a('lin'); Waiter b('liu'); b.show(); system('pause');}
问题解答
回答1:这样当然是不行的。
把一个成员声明为私有的目的就是不让你在子类中用,要是像题主这样强制类型转换之后就可以用的话还要private这个访问说明符干嘛,只留public和protected不就好了。
如果你想重载(overload)父类的函数,可以修改两行:
class Worker{ string name;public: Worker(string na):name(na){}//private:protected: // <-- 1 void data() {cout<<'worker'<<endl; }};class Waiter:virtual public Worker{public: Waiter(string na1):Worker(na1){} void show() {//((Worker &)*this).data(); ///强制转化为基类,为什么还是不能调用私有函数data()Worker::data(); // <-- 2 调用父类的同名方法data(); // <-- 3 此处会调用子类的方法 }private: void data() {cout<<'waiter'<<endl; }};回答2:
如果基类不是很复杂的话,还是有办法搞定的。声明一个与基类几乎一样的结构体或类,如果是类的话,把所有的权限都声明成public的,然后将原对象指针强制转型成你声明的新类就成了。新的结构体实现以下几点:1.需要声明原基类中从第一个到你需要访问的成员变量。比如原基类中有5个变量,你需要访问的是第3个,那结构体就声明前3个就成2.如果原基类有其它基类,那结构体也从它们派生就是了3.如果基类中有虚函数,结构体加上一个带virtual的析构函数。4.对齐方式要与基类相同按照这个方式,基本上就都能搞定了不要说什么破坏封装性的话,原罪在基类的设计者考虑不周到