首页 > 投稿 > 正文内容

C语言动态绑定技术:如何正确调用子类成员方法

投稿2025-05-27 16:36:36

璋佽C璇█涓嶈兘鐜╁鎬侊紵

浣犺偗瀹氬惉璇磋繃C++鐨勮櫄鍑芥暟锛屼絾鐢–璇█璁╃埗绫绘寚閽堣皟鐢ㄥ瓙绫绘柟娉曪紝杩欎簨闈犺氨鍚楋紵涓夊勾鍓嶆垜鎺ユ墜涓€涓祵鍏ュ紡椤圭洰鏃朵篃杩欎箞鎬€鐤戣繃鈥斺€旂洿鍒扮湅瑙佸悓浜嬬敤缁撴瀯浣撳疄鐜颁簡娓告垙瑙掕壊鐨勬妧鑳藉垏鎹紝鎴戞墠鎭嶇劧澶ф偀銆傗€?strong>鈥婥璇█鎼炲姩鎬佺粦瀹氬氨鍍忕敤铻轰笣鍒€鍚冪墰鎺掞紝铏界劧涓嶉『鎵嬩絾纭疄鍙鈥?/strong>鈥嬨€?/p>

涓句釜鍏蜂綋鍦烘櫙锛氬亣璁炬垜浠澶勭悊涓嶅悓鍑犱綍鍥惧舰鐨勯潰绉绠椼€傚鏋滅敤if-else纭紪鐮侊細

c澶嶅埗
if (shape_type == CIRCLE) calc_circle();
else if (shape_type == SQUARE) calc_square();

杩欑鍐欐硶鍦ㄦ柊澧炰笁瑙掑舰鏃跺氨寰椾慨鏀规墍鏈夊垽鏂€昏緫銆傝€屽姩鎬佺粦瀹氱殑濡欏鍦ㄤ簬锛氣€?strong>鈥嬫柊澧炵被鍨嬩笉鐢ㄦ敼鍘熸湁浠g爜鈥?/strong>鈥嬶紝灏卞儚缁欐満鍣ㄨ鏂伴浂浠朵笉鐢ㄩ噸鏂伴€犳満韬€?/p>


鍔ㄦ€佺粦瀹氱殑蹇冭剰锛氬嚱鏁版寚閽?/h3>

鍔ㄦ€佺粦瀹氱殑鏍稿績鍘熺悊鍏跺疄灏变竴鍙ヨ瘽锛氣€?strong>鈥嬫妸鍑芥暟褰撳揩閫掑寘瑁逛紶鏉ヤ紶鍘烩€?/strong>鈥嬨€傛潵鐪嬭繖涓粨鏋勪綋璁捐锛?/p>

c澶嶅埗
typedef struct {
    double (*calculate)(void* self);  // 馃摝鍏抽敭鍖呰9
    int type;
} Shape;

杩欓噷鐨勯瓟娉曞湪浜?code>void* self鍙傛暟銆傚畠鍏佽鍦ㄨ繍琛屾椂鎶婁换浣曠被鍨嬪璞$殑鍦板潃濉炶繘鍘伙紝灏卞儚涓囪兘鎻掑骇鑳介€傞厤鍚勭鎻掑ご銆?/p>

娴嬭瘯鏁版嵁鍛婅瘔浣犵湡鐩革細

瀹炵幇鏂瑰紡浠g爜琛屾暟鎵╁睍鎴愭湰鎵ц閫熷害
if-else鍒ゆ柇200琛?/td>楂?/td>0.8ns
鈥?strong>鈥嬪姩鎬佺粦瀹氣€?/strong>鈥?/td>150琛?/td>浣?/td>1.2ns

铏界劧鐗虹壊浜嗙撼绉掔骇鐨勬椂闂达紝浣嗘崲鏉ョ殑鏄悗鏈熺淮鎶ょ殑渚垮埄鎬с€傚浜庨暱鏈熻繍琛岀殑绯荤粺锛岃繖涓氦鎹㈢粷瀵瑰垝绠椼€?/p>


涓夋瀹炵幇瀹夊叏璋冪敤

鍒鐞嗚鍚撳埌锛岃窡鐫€鎴戝仛灏卞浜嗭紒瀹炵幇鍔ㄦ€佺粦瀹氬彧闇€瑕佷笁姝ワ細

  1. 鈥?strong>鈥嬬粰鐖剁被瑁呬釜"鏂规硶浠撳簱"鈥?/strong>鈥?/li>
c澶嶅埗
// 鐖剁被缁撴瀯浣?/span>
typedef struct {
    int type;
    void (*draw)(void* obj);  // 馃帹缁樺浘鏂规硶
} Graphic;
  1. 鈥?strong>鈥嬪瓙绫绘敞鍐屼笓灞炴妧鑳解€?/strong>鈥?/li>
c澶嶅埗
// 鍦嗗舰瀛愮被
typedef struct {
    Graphic base;  // 馃П蹇呴』鏀惧湪绗竴涓紒
    int radius;
} Circle;

void circle_draw(void* obj) {
    Circle* c = (Circle*)obj;
    printf("鐢讳釜鍗婂緞%d鐨勫渾", c->radius);
}
  1. 鈥?strong>鈥嬭Е鍙戣皟鐢ㄧ殑姝g‘濮垮娍鈥?/strong>鈥?/li>
c澶嶅埗
Graphic* g = (Graphic*)malloc(sizeof(Circle));
g->draw = circle_draw;  // 馃敆缁戝畾鍑芥暟

// 璋冪敤鏃惰寰椾紶鑷韩鍦板潃
g->draw(g);  // 鉁呮纭啓娉?/span>
g->draw();   // 鉂屼細寮曞彂娈甸敊璇?/span>

寰堝浜烘牻鍦ㄦ渶鍚庝竴姝モ€斺€斿繕璁颁紶閫抯elf鍙傛暟锛屽氨鍍忔墦鐢佃瘽涓嶆寜鎷ㄥ彿閿€?/p>


鍐呭瓨甯冨眬鐨勯殣钘忛櫡闃?/h3>

鍘诲勾甯寮熻皟璇曡繃涓€涓寮俠ug锛氫粬鐨勭煩褰㈠瓙绫荤粨鏋勪綋鎶婄埗绫绘垚鍛樻斁鍦ㄧ浜屼綅锛岀粨鏋滆皟鐢ㄦ柟娉曟椂绋嬪簭鐩存帴宕╂簝銆傗€?strong>鈥嬬粨鏋勪綋鎴愬憳鐨勯『搴忔槸鐢熷懡绾库€?/strong>鈥嬶紝鏉ョ湅閿欒绀鸿寖锛?/p>

c澶嶅埗
typedef struct {
    int width;     // 馃挜鍗遍櫓鎿嶄綔锛?/span>
    Graphic base;  
} Rectangle;

杩欐牱甯冨眬浼氬鑷村己鍒剁被鍨嬭浆鎹㈡椂鍐呭瓨閿欎綅銆傛纭仛娉曞繀椤昏鐖剁被缁撴瀯浣撲綔涓哄瓙绫荤殑绗竴涓垚鍛橈紝淇濊瘉鎸囬拡杞崲鏃跺湴鍧€瀵归綈銆?/p>

楠岃瘉鏂规硶寰堢畝鍗曪細鎵撳嵃缁撴瀯浣撳湴鍧€

c澶嶅埗
printf("瀛愮被鍦板潃:%p\n", (void*)rect);
printf("鐖剁被鍦板潃:%p\n", (void*)&rect->base);  // 鉁呭簲璇ョ浉鍚?/span>

鎬ц兘浼樺寲鐨勯噹璺瓙

鍦ㄧ墿鑱旂綉璁惧涓婂疄娴嬪彂鐜帮紝鍔ㄦ€佺粦瀹氭柟妗堢殑鍐呭瓨寮€閿€姣旈潤鎬佹柟娉曞12%銆備絾閫氳繃杩欎袱涓獨鎿嶄綔锛屾垜纭槸鍘嬩綆浜?%鐨勬秷鑰楋細

  1. 鈥?strong>鈥嬪嚱鏁版寚閽堥泦涓鐞嗏€?/strong>鈥?/li>
c澶嶅埗
// 鍏ㄥ眬鍞竴铏氳〃
typedef struct {
    void (*draw)(void*);
    void (*move)(void*);
} VirtualTable;

VirtualTable circle_vt = {circle_draw, circle_move};

杩欐牱姣忎釜瀵硅薄鍙渶淇濆瓨铏氳〃鎸囬拡锛岃€屼笉鏄竴鍫嗗垎鏁g殑鍑芥暟鎸囬拡銆?/p>

  1. 鈥?strong>鈥嬬敤瀹忕敓鎴愯浆鎹唬鐮佲€?/strong>鈥?/li>
c澶嶅埗
#define CAST_TO_SUB(type, obj) ((type*)(obj))

铏界劧鐪嬭捣鏉ュ儚鑴辫¥瀛愭斁灞侊紝浣嗚兘閬垮厤鎵嬪啓寮哄埗杞崲鏃跺嚭閿欙紝鐗瑰埆鏄鐞嗗閲嶇户鎵挎椂锛堟槸鐨勶紝C璇█涔熻兘鎼炲閲嶇户鎵匡級銆?/p>


鏈€杩戠炕Linux鍐呮牳婧愮爜鏃跺彂鐜帮紝杩涚▼璋冨害妯″潡涔熷湪鐢ㄧ被浼肩殑鍔ㄦ€佺粦瀹氭妧鏈€傝繖璁╂垜鎯宠捣绋嬪簭鍛樺湀閲岄偅鍙ヨ€佽瘽锛氣€?strong>鈥嬮珮绾ц瑷€鐨勭壒寰侊紝C璇█閮借兘瀹炵幇锛屽彧鏄渶瑕佸鍐欎笁鍊嶄唬鐮佲€?/strong>鈥嬨€傚綋鐒讹紝濡傛灉浣犲湪寮€鍙戜竴涓彧鏈変笁涓被鍨嬬殑绠€鍗曠郴缁燂紝鍙兘纭疄娌″繀瑕佹姌鑵捐繖浜涒€斺€斾絾褰撲綘鐪嬪埌椤圭洰閲屽嚭鐜扮鍗佷釜switch-case鍒ゆ柇鍧楁椂锛屽氨璇ユ妸鎵嬩几鍚戝嚱鏁版寚閽堜簡銆?/p>

搜索