C++在多态子类中添加虚方法

Posted

技术标签:

【中文标题】C++在多态子类中添加虚方法【英文标题】:C++ add virtual method in polymorphic subclass 【发布时间】:2014-10-21 17:02:20 【问题描述】:

我有一个繁琐的类,我想重构它以用子类替换类型代码。在这个过程中的某个时刻,我有以下层次结构:

// interface
ISomeClass()
public:
    virtual foo() = 0;
    virtual ~ISomeClass();



// this class is cumbersome one with huge amount of conditional logic based on type
BaseSomeClass : public ISomeClass()
public:
    virtual foo()
       if(TYPE_0 == getType())   // finally I want to move such conditional logic in subclass
           doSmth();
        else if (TYPE_1 == getType())
           doAnother();
       
    


protected:
    virtual int getType()     // I temporary need it for refactoring issue 
        return type_;          // to replace type_ with subclasses
    

private:
    int type_;

;

// this classes is almost empty now, but I want to move there all conditional logic in future
class Implementation1 : public BaseSomeClass 
     virtual int getType()    // I temporary need it for refactoring issue 
        return TYPE_0;         // to replace type_ with subclasses
    
; 


class Implementation2 : public BaseSomeClass 
     virtual int getType()    // I temporary need it for refactoring issue 
        return TYPE_1;         // to replace type_ with subclasses
    
;

BaseSomeClass中定义了额外的虚方法getType()。如果我使用某种接口ISomeClass 指针处理所有实例,此方法的行为会是多态的吗?假设接口本身不提供这样的虚拟方法。 注意这段代码是重构的第一步,而不是最后一步。这也是一个简化的例子,实际代码有几十个这样的方法,我需要逐步重构。问题是关于 C++ 动态多态性。

【问题讨论】:

听起来Implementation1Implementation2 根本不应该是ISomeClass 层次结构的一部分,而是完全不同的类型。 你为什么不重载foo() ?即使doSmthdoAnother 必须在BaseSomeClass 中定义(目前没有理由),您也可以使用Impl1::foo()Base::doSmth();Impl2::foo()Base::doAnother(); 你的问题很清楚。你应该很容易询问编译器。 foo()删除丑陋的代码似乎是一个很好的第一步 @Jarod42 是的,这只是第一步。 【参考方案1】:

你问:

如果我使用某种接口ISomeClass 指针处理所有实例,此方法的行为会是多态的吗?假设接口本身不提供这样的虚方法。

如果接口不提供这样的虚方法,就不能指望多态行为。

Implementation1Implementation2中实现foo会更好。

class BaseSomeClass : public ISomeClass()

;

class Implementation1 : public BaseSomeClass 

   virtual void foo()
   
      doSmth();
   
; 


class Implementation2 : public BaseSomeClass

   virtual void foo()
   
      doAnother();
   
;

如果你必须使用getType(),你可以诉诸基于模板的多态行为。

template <typename D>
class BaseSomeClass : public ISomeClass()

   public:
      virtual foo()
      
         int type = D::getType();
         if(TYPE_0 == type)
         
            doSmth();
         
         else if (TYPE_1 == type)
         
            doAnother();
         
      
;

在这里,您期望D 提供接口getType()。您不妨期待D 提供接口foo

template <typename D>
class BaseSomeClass : public ISomeClass()

   public:
      virtual void foo()
      
         D::foo():
      
;

【讨论】:

这就是我最终想要达到的,这段代码只是在如此安全的逐步重构过程中的一个快照 @vard 所以你想继续迭代丑陋的代码,只是为了运行测试,而不是直接寻找合适的解决方案?我不确定这是否是个好主意。 @luk32 这段代码非常简化为我拥有的真实代码,只是为了说明问题,这是关于动态多态性细节的问题。

以上是关于C++在多态子类中添加虚方法的主要内容,如果未能解决你的问题,请参考以下文章

C++ 多态相关

关于C++的虚函数在父类的内部调用

多态虚方法重写

面向对象 多态

C++:多态公有继承中的虚方法

面向对象--多态虚方法重写抽象类接口