基类对派生类指针的引用

Posted

技术标签:

【中文标题】基类对派生类指针的引用【英文标题】:Base Class reference to Pointer of Derived Class 【发布时间】:2016-07-26 13:16:54 【问题描述】:

我希望在基类 A 中拥有对派生类中指针的引用(或指针,如果不可能的话)。 这看起来像这样:

 BaseClassController
        
          public :
            //Constructors, destructor,...

          protected :
            BaseDataClass *& m_current;
        

DerivedClassAController : public BaseClassController
    
      public :
        //Constructors, destructor,...

      protected :
        DerivedDataClassA * m_currentA;
    

DerivedClassBController : public BaseClassController
    
      public :
        //Constructors, destructor,...

      protected :
        DerivedDataClassB * m_currentB;
    

数据类为:

BaseDataClass

    void doSomething();


DerivedDataClassA : public BaseDataClass

 //...


DerivedDataClassB : public BaseDataClass

 //...

我接下来想在 BaseClassController 中做的是:

BaseClassController::someFunction()
    m_current->doSomething();

问题是 m_currentA 和 m_currentB 指向的对象在程序的整个生命周期中都会发生很大变化,我希望 m_current 引用在派生类指针更改时自动更改。 具体来说,我希望改变 m_currentA 指向的对象的函数看起来像这样:

DerivedClassAController::changerCurrentA(DerivedDataClassA* ptA)
   m_currentA = ptA;

不是这样的:

DerivedClassAController::changerCurrentA(DerivedDataClassA* ptA)
   m_currentA = ptA;
   m_current = ptA;

我尝试通过在派生类构造函数中传递指针:

BaseClassController::BaseClassController(BaseDataClass* pt)
 : m_current(pt)



DerivedClassAController::DerivedClassAController()
 : BaseClassController(m_currentA),
   m_current(A)


但我最终得到了一个 m_current 指向 DerivedClassAController 中的 DerivedDataClassB。

这可以实现吗?或者有更好的方法吗?

注意: DerivedClassAController 将在 95% 的时间内使用 m_currentA 作为 DerivedDataClassA。仅在基类中使用 m_current 指针将结束将 dynamic_cast(m_current) 放在任何地方。

【问题讨论】:

polymorphism - 你试过了吗?你能通过m_current指针做你需要的一切吗? virtual BaseDataClass* GetCurrent() = 0; in BaseClassController,并让两个派生控制器实现它并分别返回m_currentAm_currentB的当前值。 LogicStuff - 我添加了一条注释来解释为什么我不能像你建议的那样做。伊戈尔 - 可以的,是的!我会尝试。但我也想知道它是否可以按照我尝试的方式工作 如您的示例中所写,BaseClassController 构造函数将引用绑定到局部变量 ptm_currentA 的副本)。一旦构造函数返回,引用就会变得悬空。 没想到...怎么通过呢? 【参考方案1】:

我认为以下方法可行:不使用成员引用,而是在 BaseClassController 中创建一个返回指针副本的虚函数:

struct BaseClassController 
    virtual BaseDataClass* m_current() = 0;

并在每个派生控制器中以不同方式实现它:

BaseDataClass* DerivedDataClassA::m_current() 
    return m_currentA;

【讨论】:

... 并且,我建议尽可能将需要使用该指针的代码放在对象本身内部中,或者它的父级,因此根本不需要返回指针。这样,“我不必跑遍应用程序的源代码”来发现特定事物被操纵的所有方式。没关系。”如果(或者更确切地说,何时)需要更改某些内容,则只需“更改一次,就在此处”。 这是我尽可能做的事情。开发的应用程序是使用大量 MVC 设计模式的 CAD。控制器通过指针操作数据类,但程序的其余部分调用控制器的函数。指针不会远离控制器类及其基类。

以上是关于基类对派生类指针的引用的主要内容,如果未能解决你的问题,请参考以下文章

派生类和基类的转换

无法将参数 1 从派生指针转换为基类指针引用

通过基类的指针或引用调用虚函数构成多态

通过基类的指针或引用调用虚函数构成多态

为啥我不能同时实例化对基类的引用作为派生类的指针?

基类指针引用派生类对象