c++ - 如何处理类及其属性的抽象和特化?

标签 c++ design-patterns polymorphism abstract-class abstraction

为这个相当抽象的标题道歉。

更清楚:

  • 我有两个类ControlerInterface(硬件意义上的,与设计模式无关)
  • 两者都是抽象的,具有一些纯虚方法,因此打算被子类化
  • 我需要创建的每个 Controler 都与一个 Interface 对象相关联
  • 每个 Controler 子类仅与 Interface 子类的子集一起工作(ControlerA + InterfaceAControlerB + InterfaceB但不是 ControlerA + InterfaceB)
  • 每个Interface子类都有自己的方法不被继承(这就是为什么只有一种Controler可以使用它)
  • Controler基类需要调用基类Interface的一些方法

我尝试将 Interface 对象传递给 Controler 构造函数,因此在我的类定义中,Interface 属性表示抽象基类。但是如果我的 Controler 子类 A 需要调用 Interface A 的特定方法,则会引发编译错误,因为 Interface 基类没有不拥有这种方法。

我发现的唯一解决方法是调用 dynamic_cast,但显然这似乎是错误的。


这是我的接口(interface)类:

class Interface {
public:
  Interface() {};
  virtual void method() = 0;
};

class InterfaceA : public Interface {
public:
  InterfaceA() : Interface() {};
  void method() override { cout << "A overriding" << endl; }
  void onlyA() { cout << "A only" << endl; }
};

class InterfaceB : public Interface {
public:
  InterfaceB() : Interface() {};
  void method() override { cout << "B overriding" << endl; }
  void onlyB() { cout << "B only" << endl; }
};

这是我的 Controler 类:

class Controler {
public:
  Controler(Interface* i) : m_interface(i) {};
  virtual void uniqueMethod() = 0;
  void commonMethod() { m_interface->method(); }
  Interface* m_interface;
};

class ControlerA : public Controler {
public:
  ControlerA(InterfaceA* i) : Controler(i) {};
  void uniqueMethod() override {dynamic_cast<InterfaceA *>(m_interface)->onlyA();}
};

class ControlerB : public Controler {
public:
  ControlerB(InterfaceB* i) : Controler(i) {};
  void uniqueMethod() override {dynamic_cast<InterfaceB *>(m_interface)->onlyB();}
};

下面是我打算如何使用它们:

auto ia = new InterfaceA();
auto ca = ControlerA(ia);
ca.commonMethod();  // Method defined in the base class
ca.uniqueMethod();  // Method defined in InterfaceA only

您可以在 Repl.it 上试用.

有什么设计模式可以解决这个问题吗?

最佳答案

确实有问题。 m_interface的动态类型与实现Controler的对象的动态类型之间存在不变量。但是这个不变量不能由 Controler 类维护。所以 m_interface 成员不是一个正确的地方。

结果是每次调用 uniqueMethod 时都需要使用 dynamic_cast 在运行时检查此成员是否具有正确的类型。如果不变量被破坏,代码将具有 UB,因为它会取消引用空指针。

所以这实际上不是设计模式问题,而是更根本的面向对象编程建议:类必须确保不变量。

class Controler {
public:
  virtual void uniqueMethod() = 0;
  virtual void commonMethod() = 0;
};

class ControlerA : public Controler {
public:
  ControlerA(InterfaceA* i):m_interface{i} {
    assert(dynamic_cast<InterfaceA*>(i)!=nullptr);
    };
  void uniqueMethod() override { m_interface->onlyA();}
  void commonMethod() override { m_interface->method(); }
private: InterfaceA* m_interface;
};

class ControlerB : public Controler {
public:
  ControlerB(InterfaceB* i):m_interface{i} {
    assert(dynamic_cast<InterfaceB*>(i)!=nullptr);
    };
  void uniqueMethod() override { m_interface->onlyB();}
  void commonMethod() override { m_interface->method(); }
private: InterfaceB* m_interface;
};

现在,看起来我们有了一个规则模式,所以这是我们可以考虑更通用的设计的地方:

template<class Inter,void(Inter::* OnlyFunc)()>
class ControlerImpl : public Controler {
public:
  ControlerImpl(Inter* i):m_interface{i} {
    assert(dynamic_cast<Inter*>(i)!=nullptr);
    };
  void uniqueMethod() override { (m_interface->*OnlyFunc)();}
  void commonMethod() override { m_interface->method(); }
  private: Inter* m_interface;
};
using ControlerA = ControlerImpl<InterfaceA,&InterfaceA::onlyA>;
using ControlerB = ControlerImpl<InterfaceB,&InterfaceB::onlyB>;

关于c++ - 如何处理类及其属性的抽象和特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53596519/

相关文章:

C++,dll的多个实例,单例

design-patterns - Spring框架中使用了哪些设计模式?

c++ - C++(0x) 中是否存在无操作 "do nothing"函数对象?

c++ - 使用位掩码生成素数导致程序崩溃

wpf - WPF中对MVVM的一句话解释?

c++ - 错误 C2106 : '=' : left operand must be l-value c++

C - 多态 (void *) 数组

c++ - 中级: pure virtual method called

python - 你能在 Python 脚本中编译 C++ 吗?

c++ - 使用 C++ 的 MVC 方法