【问题标题】:How to pass an abstract class's derived classes as a parameter?如何将抽象类的派生类作为参数传递?
【发布时间】:2020-04-23 15:19:32
【问题描述】:

我目前正在开发用于编码和解码文本的 C++ 标头。确切地说:UTF-8、UTF-16、UCS-2 和 UTF-32。但我已经到了我的 C++ 知识无法让我更进一步的地步:

我想使用抽象类进行解码和编码,同时为每个编解码器创建基类。然后,如果使用任何与编码或解码相关的函数,开发人员应该能够将自定义数据类型传递给函数。

问题是我不知道如何实际执行此操作。毕竟,您不能将静态类作为参数传递。但我也不想硬编码任何东西。开发人员还应该能够轻松添加任何编解码器,并且无需修改我的标头。

此外,它应该尽可能简单。代码看起来像这样:

namespace Encoding {

  class Encoder {
  public:
    virtual std::string Encode(std::string sOriginal) = 0;
  };

  // Derived classes like UTF8 and UCS2 here

}

void OutputEncoded(std::string s, Encoder enc) {
  std::cout << enc.Encode(s);
}


int main() {
  OutputEncoded("Hellö Wörld!", Encoding::UTF8);
}

知道怎么做吗?也许是一种不创建对象而只使用静态方法的方法?还是我必须使用带指针的对象?

【问题讨论】:

  • 什么是静态类?
  • 你可能来自 c# 吗? C++ 没有“静态类”,我发现的唯一东西是this question,从 OP 代码中可以知道它们的含义。也许如果您包含一些代码,这也可以在这里
  • 请附上你想写的代码的minimal reproducible example,不管多坏,这将有助于澄清
  • 注释不是编写代码的最佳位置。 (如果相关)编辑您的问题(或答案),它们有更好的格式。
  • 有一些online IDEs比pastebin更合适。

标签: c++ parameters polymorphism abstract


【解决方案1】:

我自己找到了方法。其实很简单。

class Base {
public:
  virtual void DoSomething(void) = 0;
};

class Derived : public Base {
  void DoSomething(void) {
    std::cout << "Test";
  }
} DerivedTest;

Base* const DerivedTestPtr = &DerivedTest;



void Test(Base* b) {
  b->DoSomething();
}



int main() {
  Test(DerivedTestPtr);
}

【讨论】:

  • 你甚至可以避免全局变量; int main() { Derived d; Test(&amp;d); } 通过引用传递比通过指针更合适,因为nullptr 是错误的输入。
  • 您还可以澄清您的问题,因为如果没有评论中链接中的代码,则不太清楚这是在回答什么问题。我会添加代码和错误消息,然后我猜这将是一个很好的答案
  • @Jarod42 关键是让它尽可能简单。一行代码应该看起来像“EncodeString("Hello wörld", UTF8);"
  • @RobinLe 但是如果您的原始代码已经很好,那么问题是什么?
  • 如何正确操作。对我来说,它看起来太快太脏了。我认为会有更好的方法,甚至可能更有效。
【解决方案2】:

抽象类的可能替代方案是模板:

namespace Encoding {

  class UTF8 {
  public:
    static std::string Encode(std::string sOriginal);
  };
  class UCS2 {
  public:
    static std::string Encode(std::string sOriginal);
  };

}

template <typename Encoder>
void OutputEncoded(const std::string& s) {
  std::cout << Encoder::Encode(s);
}

int main()
{
  OutputEncoded<Encoding::UTF8>("Hellö Wörld!");
}

UTF8 和 UCS2 类应该尊重兼容/相同的接口,而不需要抽象类和虚拟方法提供的强制执行。

C++20 概念可能有助于强制正确使用。在 SFINAE 之前可能会用到,但更冗长。

【讨论】:

    猜你喜欢
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 2012-05-06
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多