【问题标题】:What's the best way to have a "multitype" member variable in a class?在类中拥有“多类型”成员变量的最佳方法是什么?
【发布时间】:2021-07-06 12:56:00
【问题描述】:

我目前正在为我们的代码库中已定义的类添加新功能,但由于之前没有遇到过这样的问题,我遇到了问题(我对 C++/编码还是很陌生) .下面是该类的简化版本:

class Foo {
public:
  Foo();
  ~Foo();

  Input ReturnInput() { return fizz.GetFizzInput(); }
  Output ReturnOutput() { return fizz.GetFizzOutput(); }

private:
  Fizz fizz;
};

我正在尝试使成员变量fizz 可以是不同类型的Buzz,并调用仅在Buzz 类中实现的特定方法(即GetBuzzOutput/Input())。 FizzBuzz 都继承自同一个父类,但该父类没有实现这些特定方法。

以下是我考虑过的一些选项。所有这些都需要向Foo 的构造函数添加一个参数和一个额外的成员变量,以便我们区分我们想要的类型——FizzBuzz

  1. 添加Buzz 类型的第二个成员变量,并根据需要使用任一成员变量。这似乎并不理想,因为每次构造 Foo 时,其中一个成员变量都将未被使用。

  2. 将成员变量改为指向FizzBuzz基类的指针,调用具体方法时使用dynamic_cast向下转换为合适的类型。我也不认为这是一个好主意,但我不太清楚为什么——这主要是一种感觉。

  3. Foo 拆分为两个类,FooFizzFooBuzz(每个类都有FizzBuzz 作为成员变量),并根据我们想要的类型实例化适当的版本。这似乎是最好的选择,但也许有一些我不理解的看不见的问题。

有没有更好的方法来解决这个问题?我是否错过了一些可以让这变得更容易的东西?我无法在FizzBuzz的父类中实现虚方法,很遗憾。

非常感谢您的建议。

【问题讨论】:

  • 另一种选择:std::variant<Fizz, Buzz>
  • 泛型和多态不能解决你的问题吗?
  • 听起来你已经有了 Fizz 和 Buzz 的基类,所以只需在 Foo 中添加该基类的指针,然后在创建 Foo 实例时创建适当的实例,例如std::unique_ptr<MyBase> fizzbuzz; .. fizzbuzz = std::make_unique<Buzz>();fizzbuzz = std::make_unique<Fizz>();
  • 谢谢大家的想法。不幸的是,我们锁定了 C++17 之前的 C++ 版本,所以我无法使用 std::variant。我认为我不能使用多态性,因为当我尝试调用特定方法(即GetFizzInput/Output)时,编译器会抱怨该对象没有实现相关的方法。我也许可以dynamic_pointer_cast 得到正确的类型。

标签: c++ class inheritance type-conversion


【解决方案1】:

假设给定的 Foo 对象不需要能够在运行时从hold-a-Fizz 切换到hold-a-Buzz,C++ 模板将为您提供所需的灵活性,而无需编写两个 FooFizz 的代码重复和一个 FooBuzz 类:

template <class T> class Foo {
public:
  Foo();
  ~Foo();

  Input ReturnInput() { return t.GetInput(); }
  Output ReturnOutput() { return t.GetOutput(); }

private:
  T t;
};

typedef Foo<Fizz> FooFizz;
typedef Foo<Buzz> FooBuzz;

【讨论】:

  • 感谢您的建议!一个问题,如果我使用模板类,那会不会阻止我使用与FizzBuzz(即GetFizzInput/Output)关联的函数的特定版本?
  • 这会很困难(但并非不可能);最好的解决方案是,如果您能找到一套适用于FizzBuzz 的通用方法,那么一切都“正常工作”。因为(根据您的描述)听起来FizzBuzz 都已经是同一个基类的子类,所以您已经完成了一半。
猜你喜欢
  • 1970-01-01
  • 2021-10-20
  • 2012-12-03
  • 2015-08-04
  • 2020-05-25
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多