C++ 多态性和类型细节

问题描述 投票:0回答:1

我需要有一些类来实现类似的东西(不同类型的神经网络),但接口有所不同。

做研究,我想在作曲课上用不同的神经网络运行程序。我希望能够替代现有类型的 和 。最好通过运行时启动参数来处理这个问题,但编译时放置也可以。

我看到至少 5 种方法都有其缺点,这使我无法使用它们:

  1. 用虚函数实现基类,并将指向基类的指针放入组合类中。主要缺点:对象切片的风险、克隆函数的地狱、派生类的赋值和比较运算符、dynamic_cast 或类似的肮脏技巧来识别实际对象类型以应用特定于类型的函数。
  2. 使用神经网络类型的模板。缺点:这将需要将大部分代码移至模板,因此我将不得不将大量实现代码放入头文件中。
  3. 通过添加占位符功能来统一界面。缺点:接口会变得肮脏地狱。
  4. 使用 C++ 预处理器和 #ifdef 块来分隔两个版本的代码。缺点:它是代码块的肮脏复制/粘贴,并且超过 2 个类会带来地狱。
  5. 使用适配器模式,提供统一的接口并隐藏细节。缺点:实际上,它将通过指向实现的指针来实现,因此会受到(1)和(2)的影响,但(2)仅在适配器接口中。

现代 C++ 有更好的方法来实现这一点吗?有些东西告诉我,我可以围绕使用 std::function 构造的块构建某种解决方案,但我还不确定。

c++ oop design-patterns object-oriented-analysis
1个回答
0
投票

好吧,我找到了解决方案,真的不知道为什么我昨天犯了错误,让事情变得过于复杂。

该解决方案适用于编译时。对于运行时,我将使用原始问题中的选项 (1)。

总体思路是使用具有特定类参数的重载函数,这将允许编译时多态性选择正确的函数,该函数将采用正确的类型进行设置、调整等。

解决方案

class NNType1 { … };
class NNType2 { … };

using NeuralNetwork = NNType1;
// using NeuralNetwork = NNType2;

class Creature {
    NeuralNetwork nn;
public:
  template <typename T> void setupNN(NNType1&);
  template <typename T> void tuneNN(NNType1&);
};

template<> Creature::setupNN(NNType1& nn) {
…
}

实际上,模板不是使用重载函数,而是用于简化类声明,避免所有类型的重载函数列表。

现在所有使用接口自定义部分的代码都被放入这些 setupNN/tuneNN 函数中,这些函数特定于具体类 NNType1/NNType2/等。对于 Creature 的通用代码,这些函数隐藏了实现细节。

利润

  1. 易于实施
  2. 现在代码被分割成小函数,没有 if/switch
  3. 没有使用RTTI信息,没有dynamic_casts等

有什么意见、更正、改进建议吗?

© www.soinside.com 2019 - 2024. All rights reserved.