您的位置:首页 > 其它

关于多重继承指针回退传递的细节。

2013-09-27 14:18 211 查看
引言: 在一个产品中, 看到把一个实现类指针 this, 同时传递给接口Tx, Rx 有感。

当时这个接口没有写好,子类和父类在函数原型定义上一个是const, 一个未定为const, 使得基类传递不给继承类。

这种差别,已经不能称为父子关系了。

接口工作不了,才不得不多看了一眼。并认真的思考了一下问题。

--------------------------------------------------------------------------------

关于多重继承指针回退传递的细节。

1. 问题提出

c 语言时代,有回调函数。 是说传递来一个函数指针,我们来调用这个函数。

这样我们并不关心这个函数的实现,而只是关心这个函数的接口。即它的参数类型,参数个数。

c++时代,进一步表现为。传递过来一个对象指针。我们来调用这个对象的成员函数。

这就是类的回调函数。对于正在写底层逻辑的你来说, 你不关心这个回调对象的实现,而只是

关心它的接口。

c时代,传来的函数可以有不同的地址,从而有不同的表现。

c++时代,这个传来的指针可以是不同的对象。因而也可以有不同的表现形式。但实现这种变化必须要求

各对象具有相同的基类。基类中要求变化的函数声明为虚函数,并且当函数需要不同的表现时,继承类重载基类对应的函数。

看起来,c++一下子比c复杂了不少。

c++实现这种要求的方法是通过建立虚函数表来完成的。

在还不知道未来继承类是怎样实现的情况下, 基础的逻辑控制函数就已经按照基类的要求来完成它的处理流程了。

这里碰到了一种情况。 一个实现类继承了两个虚基类Rx, Tx.

在书写函数时,已经写好了控制流程。 并且这个实现类 implemnet RXTX 也已经完成。

问题是,这个实现类对象,怎样传递给虚基类指针Rx, Tx.

我们知道,子类会退化为父类指针,对应单继承很好理解,对应多重继承, 难道说这个子类即能退化为Tx, 又能退化为Rx吗?

带着这种疑惑, 我研究了这个问题的汇编代码。 得出了结论:

子类在退化为父类指针时,并不是简单的指针赋值,而有可能调整指针位置,这就是c++编译器的强大复杂之处。

2. 研究这个问题的例子。(源码)

#include "stdafx.h"

#include <conio.h>

#include <locale.h>

#include "windows.h"

class Tx

{

public:

virtual void tx_exec() {

printf("Tx not implement!\n");

}

private:

char a;

char b;

};

class Rx

{

public:

virtual void rx_exec() {

printf("Rx not implement!\n");

}

private:

int i;

int j;

};

class RxTx: public Tx, public Rx

{

public:

void tx_exec() {printf("Tx has implement!\n");}

void rx_exec() {printf("Rx has implement!\n");}

};

void test(Tx *pTx, Rx *pRx)

{

pTx->tx_exec();

pRx->rx_exec();

}

int main(int argc, char* argv[])

{

RxTx obj;

test(&obj, &obj); // 奥妙就在这里, 前一个&obj, 与后一个&obj 是不同的地址被压栈。

// 因为obj 包含两个类,前一个地址&obj 指向 Tx 对象部分, 后一个地址&obj 指向 Rx对象部分。

// Tx对象部分,Rx对象部分第一个参数分别对应各自的虚函数表。从而实现完美退化。

_getch();

return 0;

}

阅读此文,希望你对程序架构一词有更深的理解。 架构就是架子。就是在还没有实现类的时候,就已经用基础类在运转了。

体现"实现"与"接口"的分离。 实际上就是基类和继承类分离。 就是c++ 继承概念。不同的对象表现,就是多态概念。阿弥陀佛!...

补充: 如果一个实现类需要很多的接口时, 可以采用SendMessage 的结构。 把消息用命令类型来分类。 这样就可以省略很多接口指针。

MFC 的sendmessage, postmaessage 就是很好的例子。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: