体系结构模式:处理两个相同实现的功能



我有以下问题,考虑到我面临的问题,我想我解决得不正确:

我有一个接口I和实现A, B, C...,我想以某种方式表达我可以从偶(f(A,A(,f(B,B(,f,C(等中得到一些结果。换句话说,我想用接口I表达两个相同的实现可以组合起来产生一些结果,而其他实现则不能(你不能从f(A、B(中得到任何有效的结果(。

现在我有以下内容:

#include <iostream>
using namespace std;
class A;
class B;
class I{
public:
virtual int f (const I &other) const = 0;
virtual int fSpecific (const A &other) const { throw runtime_error(""); };
virtual int fSpecific (const B &other) const { throw runtime_error(""); };
};
class A: public I{
public:
A(int a) : a(a) {} 
int f (const I &other) const override { other.fSpecific(*this); }
int fSpecific (const A &other) const override { /*logic here*/ return a + other.a; }
int a;
};
class B: public I{
public:
B(int b1, int b2) : b1(b1), b2(b2) {}
int f (const I &other) const override { other.fSpecific(*this); }
int fSpecific (const B &other) const override { /*logic here*/ return b1*b1 + b2*b2 + other.b1*other.b1 + other.b2*other.b2; }
private:
int b1;
int b2;
};
int f(const I &a, const I &b) {
a.f(b);
}
int main()
{
cout << f(A(1), A(2)) << std::endl; // prints 3
cout << f(B(1, 2), B(3, 4)) << std::endl; // prints 30
cout << f(A(1), B(3, 4)) << std::endl; // throws an error
return 0;
}
/*and so on*/

但我想我用错了架构。因为添加类导致改变CCD_ 3。有没有更好的解决方案来表达这种关系?

您的接口确实很奇怪,请求不应该实现的方法。

我们没有多重动态调度,除了std::variantstd::visit

所以以下可能会有所帮助:

using V = std::variant<A, B, C>;
int f(const V& v1, const V& v2) {
struct {
template <typename T1, typename T2>
int operator()(const T& t1, const T2& t2) const { throw runtime_error(""); };
int operator()(const A& a1, const A& a2) const { return a1.a + a2.a; };
int operator()(const B& b1, const B& b2) const { return b1.b1*b1.b1 + b1.b2*b1.b2 + b2.b1*b2.b1 + b2.b2*b2.b2; };
int operator()(const C& c1, const C& c2) const { return c1.c * c2.c; };
} visitor;
return std::visit(visitor, v1, v2);
}

或者保持你的层次结构:

using CV = std::variant<const A*, const B*, const C*>;
class I
{
public:
virtual ~I() = default;
virtual CV asVariant() const = 0;
};
class A: public I{
public:
A(int a) : a(a) {}
CV asVariant() const override { return this; }
friend int f (const A& a1, const A& a2) { /*logic here*/ return a1.a + a2.a; }
int a;
};
class B: public I{
public:
B(int b1, int b2) : b1(b1), b2(b2) {}
CV asVariant() const override { return this; }
friend int f (const B& b1, const B& b2) {
/*logic here*/ return b1.b1*b1.b1 + b1.b2*b1.b2 + b2.b1*b2.b1 + b2.b2*b2.b2;
}
private:
int b1;
int b2;
};

int f(const I& i1, const I& &2) {
struct {
template <typename T1, typename T2>
int operator()(const T1*, const T2*) const { throw runtime_error(""); };
template <typename T>
int operator()(const T* t1, const T* t2) const { return f(*t1, *t2); };
} visitor;
return std::visit(visitor, i1.AsVariant(), i2.AsVariant());
}

您可以使用dynamic_cast:

class I {
public:
template<typename T>
void fSpecific (T &other) {
if (dynamic_cast<T*>(this))
std::cout << "OK" << std::endl;
else
std::cout << "ERROR" << std::endl;
}
virtual ~I() {}
};
class A : public I { 
};
class B : public I { 
};
int main()
{
A a;
a.fSpecific(a);
B b;
b.fSpecific(a);
b.fSpecific((I&)a);
return 0;
}

然而,也存在一些问题:

  • 多重继承
  • 对象需要是动态可移植的(这就是我添加虚拟接口的原因(
  • 铸造到I也起作用

最新更新