而我的代码是印发错误的,为什么?
///////////////// .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");
}
PHPz2017-04-17 15:38:02
這樣當然是不行的。
把一個成員聲明為私有的目的就是不讓你在子類中用,要是像題主這樣強制類型轉換之後就可以用的話還要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;
}
};
黄舟2017-04-17 15:38:02
如果基類不是很複雜的話,還是有辦法搞定的。
聲明一個與基類幾乎一樣的結構體或類,如果是類的話,把所有的權限都聲明成public的,然後將原對象指針強制轉型成你聲明的新類就成了。
新的結構體實作以下幾點:
1.需要宣告原基類別中從第一個到你需要存取的成員變數。例如原基類中有5個變量,你需要訪問的是第3個,那麼結構體就聲明前3個就成
2.如果原基類有其它基類,那麼結構體也從它們派生就是了
3.如果基底類別中有虛函數,結構體加上一個帶有virtual的析構函數。
4.對齊方式要與基類相同
按照這個方式,基本上就都能搞定了
不要說什麼破壞封裝性的話,原罪在基類的設計者考慮不周到