关于 MFC C++ 多态性

Posted

技术标签:

【中文标题】关于 MFC C++ 多态性【英文标题】:About MFC C++ Polymorphism 【发布时间】:2012-08-01 12:59:18 【问题描述】:

我遇到了 MFC C++ 多态性,这是我的问题:

我有一个类,比如说 A,它实现了很多有用的东西,但是我需要从中实例化的每个对象都需要一些定制,所以我决定派生我的每个类(例如:A1、A2 ...)。 现在,这些对象的初始化需要一些对所有子类都相同的操作,所以我构建了一个静态方法来完成这项任务,问题就来了:

void CFastInit::FastGrid( const CStatic &stPosition, A *pGrid, UINT nID, CWnd *pWnd )

    stPosition.GetClientRect( rctGriPos );
    stPosition.MapWindowPoints( pWnd, rctGriPos );
    pGrid->Create( WS_CHILD | WS_VISIBLE, rctGriPos, pWnd, nID );
    pGrid->SetWholeRowSel();

从调试器中我可以看到 pGrid 的类型是正确的( A1, A2... ),但是调用:

pGrid->Create(

对 A::Create 完成,而不是对 A1::Create 或 A2::Create。有解决办法吗?

【问题讨论】:

Create()virtual 函数吗? Create是静态方法吗?如果是这样,这是预期的行为,因为静态方法绑定到特定的类(在本例中为 A)。 【参考方案1】:

看来你有一个静态函数FastGrid()。请注意,此函数由基类的所有对象共享,从基类派生的任何类的所有对象。

在此函数中,您将获得一个指向基类的指针作为参数:A *pGrid,然后对该指针进行函数调用:pGrid->Create()

现在,如果pGrid 指向一个派生 类对象,如果你想拥有多态性,你需要Create() 函数是virtual。如果它不是虚拟的,则基类的Create() 函数将始终被调用。

可能你想要这样的东西:

class base

public:
    static void foo( base * ptr)
    
        ptr->bar();
    
    virtual void bar()
    
        std::cout << "base class bar() call" << std::endl;
    
;

class derived : public base

    virtual void bar()
    
        std::cout << "derived class bar() call" << std::endl;
    
;

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

    base::foo( new derived() );

输出:

derived class bar() call

如果删除virtual 关键字,输出将是

base class bar() call

这就是你现在所拥有的。另请注意,我的示例中的静态函数也可以这样调用:derived::foo( new derived() );,这不会改变任何内容。

【讨论】:

【参考方案2】:

这是因为 pGrid 的类型为“A”。您可以使用类型检查并将其强制转换为使用您想要的方法。

【讨论】:

在您回答一些其他发帖人的问题后,我会尽力提供更多帮助(这也有助于我理清问题)【参考方案3】:

忘记添加 virtual 关键字可能是您的情况的根本原因,但是,如果您从 ctor 调用实例方法,则虚拟函数也不起作用,因为编译器将确保虚拟表指针在范围内基类的ctor属于基类,派生类也是。

而且,除了虚函数之外,模板也可以用来达到类似的效果,就像你在 ATL 中看到的很多例子一样

【讨论】:

以上是关于关于 MFC C++ 多态性的主要内容,如果未能解决你的问题,请参考以下文章

关于C++的多态实现机理问题

C++编程题 关于 继承和多态 的

C++ 静态多态性 (CRTP) 和使用派生类的 typedef

对面向对象c++中多态的理解

C++进阶第十六篇——C++中的多态(多态的概念+多态的实现+抽象类+多态的原理)

探索C++对象模型