如何用C實現C++類裡面的成員?
假設現在有一個非常簡單的C++類
class Person
{
public:
int age;
char name[20];
void Get_Val()
{
printf("Input your name: ");
scanf("%c", name);
printf("Input your age: ");
scanf("%d", age);
printf("%c %d
", name, age);
}
};
Person類裡面有兩個成員name和age。如果用C去模擬的話,如何實現對成員的引用,題主只想到了一個很糟糕的解決方案。
typedef struct _Person
{
int age;
char name;
void(*Get_Val)(struct _Person *that);
} Person;void _Get_Val(Person *that)
{
printf("Input your name: ");
scanf("%c", that-&>name);
printf("Input your age: ");
scanf("%d", that-&>age);
printf("%c%d", that-&>name, that-&>age);
}
利益關係:學習8位機,想把自己寫的函數庫封裝起來
糟糕的地方在於你不應該把非虛函數變成Person的成員變數。通常來講是這麼寫的:
C++:
struct IBitch
{
int bitch = 0;
Bitch(int _bitch):bitch(_bitch){}
virtual ~IBitch() = default;
virtual int Bitch()const = 0;
};
struct Fuck : virtual IBitch
{
int fuck = 0;
Fuck(int _fuck):IBitch(100), fuck(_fuck)();
virtual ~Fuck()=default;
virtual int Bitch()const{ return fuck + bitch; }
};
struct Shit : virtual IBitch
{
int shit = 0;
Fuck(int _shit):IBitch(100), shit(_shit)();
virtual ~Shit()=default;
virtual int Bitch()const{ return shit + bitch; }
};
struct FuckShit : Fuck, Shit
{
FuckShit(int _fuck, int _shit):IBitch(100), Fuck(_fuck), Shit(_shit){}
virtual int Bitch()const{ return fuck + shit + bitch; }
}
int main()
{
const IBitch fuck = Fuck(1);
const IBitch shit = Shit(2);
const IBitch bitch = FuckShit(3, 4);
cout &<&< fuck.Bitch() &<&< "," &<&< shit.Bitch() &<&< "," &<&< bitch.Bitch() &<&< endl;
return 0;
}
C:無責任手寫請自行調試挑錯
// 偷懶去掉typedef不想遵守C語言語法
struct IBitch;
struct Fuck;
struct Shit;
struct FuckShit;
/***************************************************
IBitch
***************************************************/
struct vtable_IBitch
{
void(*__dtor)(IBitch*);
int(*Bitch)(IBitch*);
};
vtable_IBitch __vtable_IBitch_IBitch;
struct IBitch
{
vtable_IBitch* __vtable;
int bitch;
};
void __ctor_IBitch(IBitch* __this, int _bitch)
{
__this-&>__vtable = __vtable_IBitch_IBitch;
__this-&>bitch = _bitch;
}
void __dtor_IBitch(IBitch* __this)
{
}
void __virtual_dtor_IBitch(IBitch* __this)
{
__dtor_IBitch(__this);
}
/***************************************************
Fuck
***************************************************/
struct Fuck
{
IBitch* __base_IBitch;
int fuck;
};
struct __final_Fuck
{
Fuck __base_Fuck;
IBitch __base_Bitch;
};
vtable_IBitch __vtable___final_Fuck_IBitch;
void __ctor_Fuck(Fuck* __this, IBitch* __base_IBitch, int _fuck)
{
__this-&>__base_IBitch = __base_IBitch;
__this-&>fuck = _fuck;
}
void __dtor_Fuck(Fuck* __this)
{
}
void __ctor___final_Fuck(__final_Fuck* __this, int _fuck)
{
__ctor_IBitch(__this-&>__base_Bitch, 100);
__this-&>__base_Bitch.__vtable = __vtable___final_Fuck_IBitch;
__this-&>__base_Fuck.__base_IBitch = __this-&>__base_Bitch;
__ctor_Fuck(__this-&>__base_Fuck, __this-&>__base_Bitch, _fuck);
}
void __virtual_dtor___final_Fuck(IBitch* __this)
{
int offset = offsetof(__final_Fuck, __base_Bitch);
__final_Fuck* object = reinterpret_cast&<__final_Fuck*&>(reinterpret_cast&
__dtor_Fuck(object-&>__base_Fuck);
__dtor_IBitch(object-&>__base_Bitch);
}
int __member_Fuck_Bitch(Fuck* __this)
{
return __this-&>fuck + __this-&>__base_IBitch-&>bitch;
}
int __virtual___final_Fuck_Bitch(IBitch* __this)
{
int offset = offsetof(__final_Fuck, __base_Bitch);
__final_Fuck* object = reinterpret_cast&<__final_Fuck*&>(reinterpret_cast&
return __member_Fuck_Bitch(object-&>__base_Fuck);
}
/***************************************************
Shit
***************************************************/
struct Shit
{
IBitch* __base_IBitch;
int shit;
};
struct __final_Shit
{
Shit __base_Shit;
IBitch __base_Bitch;
};
vtable_IBitch __vtable___final_Shit_IBitch;
void __ctor_Shit(Shit* __this, IBitch* __base_IBitch, int _shit)
{
__this-&>__base_IBitch = __base_IBitch;
__this-&>shit = _shit;
}
void __dtor_Shit(Shit* __this)
{
}
void __ctor___final_Shit(__final_Shit* __this, int _shit)
{
__ctor_IBitch(__this-&>__base_Bitch, 100);
__this-&>__base_Bitch.__vtable = __vtable___final_Shit_IBitch;
__this-&>__base_Shit.__base_IBitch = __this-&>__base_Bitch;
__ctor_Shit(__this-&>__base_Shit, __this-&>__base_Bitch, _shit);
}
void __virtual_dtor___final_Shit(IBitch* __this)
{
int offset = offsetof(__final_Shit, __base_Bitch);
__final_Shit* object = reinterpret_cast&<__final_Shit*&>(reinterpret_cast&
__dtor_Shit(object-&>__base_Shit);
__dtor_IBitch(object-&>__base_Bitch);
}
int __member_Shit_Bitch(Shit* __this)
{
return __this-&>shit + __this-&>__base_IBitch-&>bitch;
}
int __virtual___final_Shit_Bitch(IBitch* __this)
{
int offset = offsetof(__final_Shit, __base_Bitch);
__final_Shit* object = reinterpret_cast&<__final_Shit*&>(reinterpret_cast&
return __member_Shit_Bitch(object-&>__base_Shit);
}
/***************************************************
FuckShit
***************************************************/
struct FuckShit
{
IBitch* __base_IBitch;
Fuck __base_Fuck;
Shit __base_Shit;
};
struct __final_FuckShit
{
FuckShit __base_FuckShit;
IBitch __base_Bitch;
};
vtable_IBitch __vtable___final_FuckShit_IBitch;
void __ctor_FuckShit(FuckShit* __this, IBitch* __base_IBitch, int _fuck, int _shit)
{
__this-&>__base_IBitch = __base_IBitch;
__ctor_Fuck(__this-&>__base_Fuck, __base_IBitch, _fuck);
__ctor_Shit(__this-&>__base_Shit, __base_IBitch, _shit);
}
void __dtor_FuckShit(FuckShit* __this)
{
__dtor_Fuck(__this-&>__base_Fuck);
__dtor_Shit(__this-&>__base_Shit);
}
void __ctor___final_FuckShit(__final_FuckShit* __this, int _fuck, int _shit)
{
__ctor_IBitch(__this-&>__base_Bitch, 100);
__this-&>__base_Bitch.__vtable = __vtable___final_FuckShit_IBitch;
__this-&>__base_FuckShit.__base_IBitch = __this-&>__base_Bitch;
__ctor_FuckShit(__this-&>__base_FuckShit, __this-&>__base_Bitch, _fuck, _shit);
}
void __virtual_dtor___final_FuckShit(IBitch* __this)
{
int offset = offsetof(__final_FuckShit, __base_Bitch);
__final_FuckShit* object = reinterpret_cast&<__final_FuckShit*&>(reinterpret_cast&
__dtor_FuckShit(object-&>__base_FuckShit);
__dtor_IBitch(object-&>__base_Bitch);
}
int __member_FuckShit_Bitch(FuckShit* __this)
{
return __this-&>__base_Fuck.fuck + __this-&>__base_Shit.shit + __this-&>__base_IBitch-&>bitch;
}
int __virtual___final_FuckShit_Bitch(IBitch* __this)
{
int offset = offsetof(__final_FuckShit, __base_Bitch);
__final_FuckShit* object = reinterpret_cast&<__final_FuckShit*&>(reinterpret_cast&
return __member_FuckShit_Bitch(object-&>__base_FuckShit);
}
/***************************************************
Config
***************************************************/
void Config()
{
__vtable_IBitch_IBitch.__dtor = __virtual_dtor_IBitch;
__vtable_IBitch_IBitch.Bitch = nullptr;
__vtable___final_Fuck_IBitch.__dtor = __virtual_dtor___final_Fuck;
__vtable___final_Fuck_IBitch.Bitch = __virtual___final_Fuck_Bitch;
__vtable___final_Shit_IBitch.__dtor = __virtual_dtor___final_Shit;
__vtable___final_Shit_IBitch.Bitch = __virtual___final_Shit_Bitch;
__vtable___final_FuckShit_IBitch.__dtor = __virtual_dtor___final_FuckShit;
__vtable___final_FuckShit_IBitch.Bitch = __virtual___final_FuckShit_Bitch;
}
/***************************************************
Main
***************************************************/
int main()
{
__final_Fuck __temp_fuck;
__final_Shit __temp_shit;
__final_FuckShit __temp_bitch;
IBitch* fuck;
IBitch* shit;
IBitch* bitch;
Config();
__ctor___final_Fuck(__temp_fuck, 1);
__ctor___final_Shit(__temp_shit, 2);
__ctor___final_FuckShit(__temp_bitch, 3, 4);
fuck = __temp_fuck.__base_Bitch;
shit = __temp_shit.__base_Bitch;
bitch = __temp_bitch.__base_Bitch;
cout &<&< fuck-&>__vtable-&>Bitch(fuck) &<&< "," &<&< shit-&>__vtable-&>Bitch(shit) &<&< "," &<&< bitch-&>__vtable-&>Bitch(bitch) &<&< endl;
bitch-&>__vtable-&>__dtor(bitch);
shit-&>__vtable-&>__dtor(shit);
fuck-&>__vtable-&>__dtor(fuck);
return 0;
}
自行參考《深入探索C++對象模型》
……既然C不是OOP你就彆強求著用OO的方式來寫。就按照PO來寫,建個函數接受Person struct的指針就完了。別在struct裡面建函數指針,你又不是要寫虛函數。
你可以用GObject那一套。
GObject Reference Manual動態特性比C++要徹底得多,就是宏有點噁心。
建議看一下glib源碼,裡面有用c實現類,繼承,介面等完整的方法。
有本書叫做 Object-Oriented Programming With ANSI-C
繼承通過指針就能模擬,也能大概實現公有私有,但實現不了友元,至於成員函數,個人認為(補充:你這樣子)把函數指針放結構體里是不妥的,函數重載也能模擬,只是太太太費勁。大概功能模擬完了,剩下的就靠自己想像了,。好了,這就是一個完美的類,是不!
普通成員方法用函數指針。虛成員方法自己實現虛表,具體可參考《深入探索C++對象模型》一書。
關鍵就是實現虛表
推薦閱讀:
※socket拋出Cant assign requested address,問題所在以及解決方法?
※C++序列化json字元串對Unicode有哪些特殊處理?
※今天面試C++,機試面試官看完代碼說代碼結構混亂?
※C++primer中一個疑似錯誤?
※初學者學c++應該做什麼準備?