为这个抽象头衔致歉。
更清楚:
1 -> 2 -> 3 -> ... 9 -> NULL
和Controler
(具有硬件意义,与设计模式无关)Interface
与一个Controler
对象相关联Interface
子类仅适用于Controler
子类的子集(Interface
或ControlerA + InterfaceA
,但不适用于ControlerB + InterfaceB
)ControlerA + InterfaceB
子类都有自己的不继承的方法(这就是为什么Interface
只有一种可以使用它的原因)Controler
基类需要调用基类Controler
的某些方法我尝试将Interface
对象传递给Interface
构造函数,因此在我的类定义中,Controler
属性表示抽象基类。但是,如果我的Interface
子类A需要调用Controler
A的特定方法,则会由于Interface
基类不拥有此方法而引发编译错误。
我发现的唯一解决方法是致电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();}
};
您可以在Repl.it上试用。
是否有解决此问题的设计模式?
答案 0 :(得分:2)
确实有问题。在m_interface
的动态类型和实现Controler
的对象的动态类型之间存在不变性。但是Controler
类无法维护此不变性。因此,m_interface
成员不是正确的位置。
其结果是,您需要在运行时每次调用dynamic_cast
时使用uniqueMethod
来检查此成员的类型正确。如果不变量被破坏,则代码将具有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>;