【问题标题】:Inheritance without pointers没有指针的继承
【发布时间】:2016-05-11 01:16:00
【问题描述】:

假设我有一个具有这样一个抽象虚函数的类:

class MyClass{
  public:
    virtual void MyFunc() = 0;
};

而且我没有其他功能,也没有数据成员。我还可以保证所有继承自它的类都没有任何数据成员,并且除了MyFunc的实现之外没有其他功能。

强迫你有一个指向抽象对象的指针的最大原因(至少在我看来)是实现的大小是未知的......所以有没有办法代替指向这个类的指针只是给出类的一个实例(或伪实例)。以此为例:

void AFunction(MyFunc inst){  //Note the lack of pointer
  inst.MyFunc();  //This should call the implementation
}

那么这是可能的还是我只是一个一厢情愿的思想家?

【问题讨论】:

  • " 我也可以保证..." 你刚刚发明了一个更大、更慢的函数指针。为什么不直接使用原来的函数指针类型呢? void(*)() 会做你班级所做的一切。 std::function 会做同样的事情而且更多,但你需要为“更多”部分付费。

标签: c++ pointers inheritance


【解决方案1】:

您必须传递指针或引用。您不能按值传递,因为根据定义,这涉及复制该值;而且,根据定义,您不能复制抽象类的实例。 C++ 不能以这种方式工作。

所以,任你选:

void AFunction(MyFunc *inst){
  inst->MyFunc();
}

void AFunction(MyFunc &inst){
  inst.MyFunc();
}

这些是您的选择。子类除了虚方法实现之外是否还有其他东西,或者抽象类除了虚方法之外是否还有其他东西,都无关紧要。答案不变。

【讨论】:

    【解决方案2】:

    这是不可能的(没有引用或指针)。

    class Interface {
      public:
        virtual void F() = 0;
    };
    
    class Implementation: public Interface {
      public:
        void F() {}
    };
    
    void SomeFunction(Interface x) {}
    
    int main() {
      Implementation impl;
      SomeFunction(impl);
    }
    

    这基本上就是您的建议。如果你要编译这个:

    blah.cc:11:29: error: parameter type 'Interface' is an abstract class
    void SomeFunction(Interface x) {}
                                ^
    

    您可以使用引用,但这基本上只是具有不同语法的指针。

    void SomeFunction(Interface & x) {}
    
    int main() {
      Implementation impl;
      SomeFunction(impl);
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用std::function。您可以不使用指针按值传递它,但它的作用类似于函数的接口:

      void AFunction(std::function<void()> myfunc){
          myfunc();  //This will call the implementation
      }
      

      您可以使用 lambda 创建这个“接口”:

      MyClass mc;
      auto myfunc = [mc]{mc.MyFunc();};
      AFunction(myfunc);
      

      在内部,std::function 使用类型擦除。

      您可以创建自己的可以按值传递的包装器,但您可能需要在内部使用某种指针。

      【讨论】:

        猜你喜欢
        • 2013-06-13
        • 1970-01-01
        • 1970-01-01
        • 2016-09-02
        • 2017-12-28
        • 1970-01-01
        • 1970-01-01
        • 2011-02-11
        • 1970-01-01
        相关资源
        最近更新 更多