简体   繁体   English

为什么基类函数不被覆盖?

[英]Why is the base-class function not overridden?

I override the base-class function ShowProperties in a sub-class, but still the base-class function gets called. 我在子类中重写了基类函数ShowProperties ,但是仍然调用了基类函数。 Why is this? 为什么是这样?

class hierarchy: 类层次结构:

class CDiagramEntity : public CObject
{
public:
  virtual void ShowProperties( CWnd* parent, BOOL show = TRUE );
}

class CNetworkSymbol : public CDiagramEntity
{
  /*NO 'ShowProperties' Function*/
}

class CDeviceEntity : public CNetworkSymbol
{
  /*NO 'ShowProperties' Function*/
}

class CSwitch : public CDeviceEntity
{
public:
  virtual void ShowProperties( CWnd* parent, BOOL show = TRUE );
}

Use: 采用:

/*Use Here*/
{
  CDiagramEntity* obj = GetSelectedObject();
  if( obj )
  {
    CSwitch* sw = (CSwitch*)obj;
     sw->ShowProperties( this );    
     /*calls CDiagramEntity's function, not CSwitch's function*/
  }
}

PS: PS:

  1. As @iammilind suggests, I removed virtual from CDiagramEntity and use casting, the function of CSwitch is called, and from the properties it shows(the properties can only be changed to what it shows when CSwitch is created), I am quite sure it is a CSwitch. 正如@iammilind所建议的,我从CDiagramEntity中删除了virtual并使用了强制转换,调用了CSwitch的功能,并从其显示的属性中(属性只能更改为创建CSwitch时显示的内容),我确定CSwitch。
  2. As @user1610015 comments, if I use 作为@ user1610015的评论,如果我使用

     CSwitch* sw = dynamic_cast<CSwitch*>(obj); 

    it returns NULL . 它返回NULL

  3. As @Andrian Sham says, I got the problem's reason: 正如@Andrian Sham所说,我有问题的原因:

     GetSelectedObject()--->finally calls---> { CDiagramEntity* result = NULL; if ( index < m_objs.GetSize() && index >= 0 ) result = static_cast< CDiagramEntity* >( m_objs.GetAt( index ) ); /*m_objs is defined as: CObArray m_objs;*/ return result; } 

m_objs: M_OBJS:

CObArray m_objs;

And the object is stored as: 对象存储为:

...( CDiagramEntity* obj )
{
  obj->SetParent( this );
  m_objs.Add( obj );
  SetModified( TRUE );
}

But can someone explain this in more details? 但是有人可以更详细地解释吗?

I am not sure how you do your debug. 我不确定您如何进行调试。 You said you can see a member var of CSwitch. 您说您可以看到CSwitch的成员变量。 If you mean you inspect CSwitch* sw = (CSwitch*)obj; 如果您的意思是检查CSwitch* sw = (CSwitch*)obj; and see such var in sw , you are in fact getting in wrong. 并在sw看到这样的var,实际上您错了。 Debugger is simply "interpreting" the piece of memory pointed by sw as it is a CSwitch. 调试器只是“解释” sw指向的内存,因为它是CSwitch。 It doesn't mean that it is really a CSwitch. 这并不意味着它确实是CSwitch。

I can only thought of a case. 我只能想到一个案例。 Have you put the object instance in any STL container and get it out to put it as the select item? 您是否已将对象实例放置在任何STL容器中并拿出来作为选择项?

(I forgot MFC totally, this is just an example) (我完全忘记了MFC,这只是一个例子)

vector<CDiagramEntity> entities;  // note it is of type CDiagramEntity, not CDiagramEntity*

CSwitch aCSwitch;
entities.push_back(aCSwitch);

// later
SetItem("SomeValue", entities[i]);

You may think you entities[i] should return an instance of CSwitch but it is not. 您可能认为您的entity [i]应该返回CSwitch的实例,但事实并非如此。

(This is the best I can guess if you are pretty sure that the selected item should be a CSwitch) (如果您确定所选的项目应该是CSwitch,这是我能猜到的最好的方法)

Because the ShowProperties() is a virtual function. 因为ShowProperties()是一个virtual函数。

When virtual mechanism kicks in, the function binding happens at runtime . 当启动virtual机制时,函数绑定将在运行时发生。
If ShowProperties() is returning an object of class CDiagramEntity , then CDiagramEntity::ShowProperties() will be called irrespective of static type of type calling pointer (here sw ). 如果ShowProperties()返回的class CDiagramEntity ,则将CDiagramEntity::ShowProperties()而与调用指针的static type CDiagramEntity::ShowProperties() (此处为sw )。

Just for experiment purpose, remove the virtual keyword and run the code. 仅出于实验目的,删除virtual关键字并运行代码。 You will get the expected behavior. 您将获得预期的行为。 But beware of possible undefined behavior. 但是要提防可能的不确定行为。

Because even if you cast a CDiagramEntity object to a CSwitch object, the call is made throgh virtual dispatch. 因为即使将CDiagramEntity对象强制转换为CSwitch对象,调用也会通过虚拟调度进行。 So, if the object returned by GetSelectedObject is not actually a CSwitch, CDiagramEntity's ShowProperties is called. 因此,如果GetSelectedObject返回的对象实际上不是CSwitch,则会调用CDiagramEntity的ShowProperties。

Why are you casting the object to CSwitch? 为什么将对象投射到CSwitch? It doesn't make sense from a design perspective. 从设计角度来看,这没有任何意义。 You have a polymorphic object, and yet you want to treat it as one of its specialized derivations. 您有一个多态对象,但您仍想将其视为其特殊派生之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM