【问题标题】:How to write a derived class which specifies type parameters for a templated base如何编写派生类,为模板化基指定类型参数
【发布时间】:2017-05-08 16:54:13
【问题描述】:

我正在学习 C++,但我无法从 C# 中引入这种设计模式。如果这种模式在 C++ 中不起作用,或者我的语法不正确,我无法确定。

在示例中,我想创建一个解码 bitset 的类。

在带有泛型的 C# 中,它看起来像这样:

abstract class Base<T>
{
  public abstract T GetValue(BitArray bits);
}

class Derived : Base<MyType>
{
  public override MyType GetValue(BitArray bits)
  {
    // Do some magic to decode this bitset
  }
}

这是我在 C++ 中的幼稚尝试

template<T,Q> 
class Base
{
public:
    Base() = default;
    virtual ~Base() = 0;
    virtual T* GetValue(const std::bitset<Q>& bits) const = 0;
}

class Derived : Base<MyType, 32>
{
public:
    Derived();
    ~Derived();
    MyType* GetValue(const std::bitset<32>& bits) const;
}

MyType* Derived::GetValue(const std::bitset<32>)
{
    // Do some magic to decode this bitset
}

当我尝试编译该 C++ 代码时,编译器会抛出各种错误(我认为这在很多方面都是错误的)。

如何实现让继承类在 C++ 中为基类模板指定类型参数的模式?

【问题讨论】:

  • 您在类声明后忘记了分号。
  • MyType 是一个类,还是应该是Derived 的模板参数?
  • a class that decodes a bitset - 这是什么意思?您应该向我们展示您的MyType。此外,对于这种特殊情况,没有必要拥有虚拟基类,因为看起来这个方法应该是静态的
  • 您也很可能希望使用公共继承,而不是私有(默认情况下)。尝试将class Derived : Base 更改为class Derived : public Base

标签: c# c++ templates generics polymorphism


【解决方案1】:

当我尝试编译该 C++ 代码时,编译器会抛出各种错误(我认为这在很多方面都是错误的)。

  • 类声明后缺少分号
  • 模板声明语法错误
  • std::bitset 缺少包含
  • MyType 未定义
  • 您不应使用来自Base 的公共或受保护继承

此外,还不清楚您为什么要使用虚拟方法。您还应该从Derived::GetValue 按值返回,或者可能是指向MyType 的智能指针:

unique_ptr<MyType> Derived::GetValue(const std::bitset<32> &) {...}

Sample code:

#include <bitset>
#include <memory>

class MyType;

template<typename T, unsigned Q>
class Base
{
public:
    virtual std::unique_ptr<T> GetValue(const std::bitset<Q>& bits) const = 0;
};

class Derived : public Base<MyType, 32>
{
public:
    std::unique_ptr<MyType> GetValue(const std::bitset<32>& bits) const;
};

【讨论】:

    【解决方案2】:

    您有多个错误:

    template<T,Q>                       // Wrong
    template<typename T, std::size_t Q> // Fixed
    
    MyType* Derived::GetValue(const std::bitset<32>)         // Wrong
    MyType* Derived::GetValue(const std::bitset<32> &) const // Fixed
    

    您还需要在类声明之后使用分号,因此每个类声明之后的} 字符必须是};

    在进行这些更改(并前向声明 MyType,我假设您的代码中已声明)之后,代码编译。

    【讨论】:

      【解决方案3】:

      无意冒犯,但您的错误只是由于几个或多或少明显的错误:

      • 类声明后没有;
      • 缺少MyType 的定义
      • 缺少#incldue &lt;bitset&gt;
      • GetValue 的声明和定义不匹配
      • typename 缺少 T
      • Q 应该是 size_t

      修复那些it compiles

      #include <iostream>
      #include <bitset> //
      using namespace std;
      
      struct MyType{}; //
      
      template<typename T,size_t Q>  //
      class Base
      {
      public:
          Base() = default;
          virtual ~Base() = 0;
          virtual T* GetValue(const std::bitset<Q>& bits) const = 0;
      }; //
      
      class Derived : Base<MyType, 32>
      {
      public:
          Derived();
          ~Derived();
          MyType* GetValue(const std::bitset<32>& bits) const;
      }; //
      
      MyType* Derived::GetValue(const std::bitset<32>&) const //
      {
          // Do some magic to decode this bitset
      }
      
      
      int main() {
          // your code goes here
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-28
        • 2011-06-04
        • 1970-01-01
        • 1970-01-01
        • 2017-09-28
        相关资源
        最近更新 更多