【问题标题】:Can I use C++ templates to implement two classes which only differ by one field type?我可以使用 C++ 模板来实现两个仅在一种字段类型上有所不同的类吗?
【发布时间】:2021-06-07 23:47:12
【问题描述】:

我正在尝试为 两个 系统实现 Controller 类。每个Controller 使用一个Solver 类实例。

我已经有 两个 Solver 类实现:

class AbstractSolver { virtual void func() = 0; };
class System1Solver : AbstractSolver { void func() override; };
class System2Solver : AbstractSolver { void func() override; };

Controller 实现对于 both Solver 类型相同。我可以实现 both Controller 类...

class System1Controller { 
  public:
    System1Controller(System1Solver solver);
    System1Solver solver;
    void func() { solver.func(); };
};

class System2Controller { 
  public:
    System2Controller(System2Solver solver);
    System2Solver solver;
    void func() { solver.func(); };
};

我想复制和粘贴相同的代码。除了 solvertype 之外,System?Controller 的两个实现都相同。我可以改用模板来实现代码重用吗?

template <class SolverClass>
class Controller {
  public:
    Controller(SolverClass solver);
    SolverClass solver;
    void func() { solver.func(); };
};

class System1Controller : Controller<System1Solver>;
class System2Controller : Controller<System2Solver>;

编辑:这个例子确实有效。感谢大家确认这是完成此任务的适当方式。

/* Compile with g++ -O3 -std=c++14 -o crimes metaprogramming_crimes.cpp */

#include <iostream>

class AbstractSolver { virtual void func() = 0; };
class System1Solver : AbstractSolver { public: void func() override { }; };
class System2Solver : AbstractSolver { public: void func() override { }; };

/* 
class System1Controller { 
  public:
    System1Solver solver;
    void func() { solver.func(); };
};

class System2Controller { 
  public:
    System2Controller(System2Solver solver);
    System2Solver solver;
    void func() { solver.func(); };
}; 
*/

template <class SolverClass>
class Controller {
  public:
    SolverClass solver;
    void func() { solver.func(); };
};

class System1Controller : Controller<System1Solver> { };
class System2Controller : Controller<System2Solver> { };

auto main()->int {

    System1Controller controller1;
    System2Controller controller2;

    if (typeid(controller1) != typeid(controller2)) {
        std::cout << "Yay!" << std::endl;
    } else {
        std::cout << "Boo." << std::endl;
    }

};

【问题讨论】:

  • 你试过了吗?我看不出它有什么不起作用的原因。
  • 吹毛求疵,你想“实现”代码重用,你尽量不要重复自己。
  • 为什么不只使用AbstractSolver 并且只有一个Controller 类?
  • 这取决于求解器变量的生命周期。如果控制器需要获取求解器的副本,那么多态解决方案将不起作用。但是,当控制器需要它时,求解器仍然存在,那么没关系,模板版本可以工作:这是每个示例:onlinegdb.com/r1vmTTB7O
  • @sweenish 谢谢你,好收获!

标签: c++ class templates subclass


【解决方案1】:

另一种选择是使用多态性:在单个 Controller 类中保留指向 AbstractSolver 的指针,并将适当的具体求解器传递给控制器​​的构造函数。

【讨论】:

  • 您可能希望在Controller 中使用unique_ptr 成员来管理AbstractSolver 对象的生命周期。
【解决方案2】:

这个例子确实有效。感谢大家确认这里使用了元类。

metaprogramming_crimes.cpp

/* Compile with g++ -O3 -std=c++14 -o crimes metaprogramming_crimes.cpp */

#include <iostream>

class AbstractSolver { virtual void func() = 0; };
class System1Solver : AbstractSolver { public: void func() override { }; };
class System2Solver : AbstractSolver { public: void func() override { }; };

/* 
class System1Controller { 
  public:
    System1Solver solver;
    void func() { solver.func(); };
};

class System2Controller { 
  public:
    System2Controller(System2Solver solver);
    System2Solver solver;
    void func() { solver.func(); };
}; 
*/

template <class SolverClass>
class Controller {
  public:
    SolverClass solver;
    void func() { solver.func(); };
};

class System1Controller : Controller<System1Solver> { };
class System2Controller : Controller<System2Solver> { };

auto main()->int {

    System1Controller controller1;
    System2Controller controller2;

    if (typeid(controller1) != typeid(controller2)) {
        std::cout << "Yay!" << std::endl;
    } else {
        std::cout << "Boo." << std::endl;
    }

};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2011-10-20
    • 1970-01-01
    • 2016-07-19
    相关资源
    最近更新 更多