关于 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++ 静态多态性 (CRTP) 和使用派生类的 typedef