【问题标题】:No viable conversion between Derived Class (constructor has parameters) and Base Class (constructor is absent of parameters)派生类(构造函数有参数)和基类(构造函数没有参数)之间没有可行的转换
【发布时间】:2020-05-02 07:29:10
【问题描述】:

我有一个包含 handle() 方法(以及其他方法)的抽象类 Handle()。这个类被实现了多次,每个类以不同的方式处理不同类型的数据(存储为字节),例如

class BaseHandle
{
   virtual void handle(uint8_t *ptr, uint8_t data_size) = 0;
}

class DerivedHandleA : public BaseHandle 
{
   void handle(uint8_t *ptr, uint8_t data_size)
   {
      //DO THINGS WITH DATA OF KIND "A"
   }
}


class DerivedHandleB : public BaseHandle 
{
   void handle(uint8_t *ptr, uint8_t data_size)
   {
      //DO THINGS WITH DATA OF KIND "B"
   }
}

我的问题是,在处理某些类型的数据时,handle() 方法需要访问其他类的实例来调用它们的成员函数,我通常会通过构造函数传递,所以目前我的代码是这样的:

class DerivedHandleC : BaseHandle 
{
private:
   HelperClass helper;

   void handle(uint8_t *ptr, uint8_t data_size)
   {
      //DO THINGS WITH DATA OF KIND "C" WITH FUNCTIONS FROM helper
   }

public:
   DerivedHandleC(HelperClass helper) : BaseHandle() helper(helper){};
}

出现问题是因为我有一个包含 Handler 类的每个实例的 std::vector,每次我获取数据时都会迭代它以找到正确的处理程序并发送数据。这适用于不带参数的 DerivedHandle,但对于带参数的构造函数,我在将其推送到我的向量时收到 no viable conversion from 'DerivedHandleC' to 'BaseHandle',这是可以理解的。

我的问题是,我应该怎么做而不是通过构造函数传递我需要的参数?我不希望简单地将相同的参数添加到不需要它们的所有派生类中,尽管我知道这将解决我的编译错误。


编辑

根据要求添加 std::vector 代码:

声明

   typedef std::vector<std::unique_ptr<BaseHandler>> HandlerVec;
   HandlerVec handlers;

回退法

registerHandler(std::unique_ptr<BaseHandler> handler)
{
   handlers.push_back(std::move(handler));
}

pushback 调用示例

registerHandler(std::make_unique<DerivedHandleA>());
registerHandler(std::make_unique<DerivedHandleC>(helper));

【问题讨论】:

标签: c++ constructor interface virtual


【解决方案1】:

与使用struct 声明的类类型相比,使用class 关键字声明的类类型默认具有私有继承。

这是一个例子:

struct A {};

struct B : A {
    // inherit publicly from A, the outside world can see the inheritance graph 
};

class C : A {
    // privately inherit, the outside world cannot see the inheritance
};

要公开继承,请使用struct 或使用带有说明符的类来覆盖默认行为:

class D : public A {
    // inherit publicly
};

【讨论】:

  • 谢谢,事实证明指定公共覆盖解决了我的问题! (使用我的示例类)我已经宣布 DerivedHandleA 和 DerivedHandleB 公开,但没有公开 DerivedHandleC,这是我犯下的愚蠢错误!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-14
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 1970-01-01
  • 2022-01-17
  • 2016-07-19
相关资源
最近更新 更多