[英]Runtime polymorphism for two different classes
我有兩個B
和Y
類,我無法按要求更改或編輯。 它們具有相同功能但具有不同名稱的功能。
我希望有一個通用的接口,在運行時根據一些輸入變量選擇類,如下面的代碼所述。 我不確定應該使用哪種設計模式。 如何創建WrapperYB
類,根據創建的對象選擇Y::show
或B::showing
。
class A
{
public:
A() {}
virtual ~A();
virtual void show() { cout << "show A" << endl;}
};
class B:A
{
public:
B() {}
virtual ~B();
virtual void show() { cout << "show B" << endl;}
};
class X
{
char m_i;
public:
Y() { m_i = 'X';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class Y:X
{
public:
Y() { m_i = 'Y';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class WrapperYB
{
// to be implemented
public:
explicit WrapperYB(const int& type);
void show();
};
int main(){
WrapperYB objY(1);
objY.show(); // must call Y::showing
WrapperYB objB(0);
objB.show(); // must call B::show
}
如果您的編譯器支持C ++ 17 Standard,您可以使用std::variant
嘗試此解決方案。 這與@Nicolas的答案中的解決方案類似,但variant
將為您處理實現細節,不會使用動態內存分配,並支持其他內容,如復制和分配。
#include <variant>
#include <utility>
#include <type_traits>
class WrapperYB {
public:
using variant_type = std::variant<Y, B>;
template <typename... Args,
std::enable_if_t<std::is_constructible_v<variant_type, Args...>>* = nullptr>
WrapperYB(Args&& ... args) : m_variant(std::forward<Args>(args)...) {}
variant_type& variant() noexcept { return m_variant; }
const variant_type& variant() const noexcept { return m_variant; }
void show()
{ std::visit(ShowImpl{}, m_variant); }
private:
struct ShowImpl {
void operator() (Y& y) const { y.showing(); }
void operator() (B& b) const { b.show(); }
};
variant_type m_variant;
};
您可以通過讓它包含std::unique_ptr<A>
或std::unique_ptr<X>
來概括包裝器。
我提議這個:
#include <iostream>
using namespace std;
class A
{
public:
A() {}
virtual ~A() {}
virtual void show() { cout << "show A" << endl;}
};
class B:A
{
public:
B() {}
virtual ~B() {}
virtual void show() { cout << "show B" << endl;}
};
class X
{
protected:
char m_i;
public:
X () { m_i = 'X';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class Y:X
{
public:
Y() { m_i = 'Y';}
virtual void showing() { cout << "showing " << m_i << endl;}
};
class WrapperYB
{
public:
enum class Which { B, Y };
public:
explicit WrapperYB (int n)
: which(Which(n))
{
switch (which)
{
case Which::B: ptr.b = new B; break;
case Which::Y: ptr.y = new Y; break;
}
}
~WrapperYB ()
{
switch (which)
{
case Which::B: delete ptr.b; break;
case Which::Y: delete ptr.y; break;
}
}
WrapperYB (const WrapperYB&) = delete;
WrapperYB& operator = (const WrapperYB&) = delete;
public:
void show()
{
switch (which)
{
case Which::B: ptr.b->show() ; break;
case Which::Y: ptr.y->showing(); break;
}
}
private:
Which which;
union {
Y* y;
B* b;
} ptr;
};
int main(){
WrapperYB objY(1);
objY.show(); // must call Y::showing
WrapperYB objB(0);
objB.show(); // must call B::show
}
它不是“香草”設計模式,我不認為,更多的適配器和歧視聯合的組合。
請注意,無法復制或分配WrapperYB。
您可以將標准虛擬分派方法與抽象基本適配器類和所需的每個對象類型的子類一起使用。 使用工廠方法創建對象。
#include <memory>
//pre-defined structures Y, B
struct Y
{
Y(){}
~Y(){}
void show(){}
};
struct B
{
B(){}
~B(){}
void showing(){}
};
// Abstract adaptor base class.
struct Adaptor
{
virtual void show() = 0;
};
// A subclass of Adaptor for each type of object to be wrapped.
struct Adaptor_Y: Adaptor
{
Adaptor_Y(): y(){}
void show() override
{
y.show();
}
private:
Y y;
};
struct Adaptor_B: Adaptor
{
Adaptor_B(): b(){}
void show() override
{
b.showing();
}
private:
B b;
};
// Factory method constructs the proper object and returns a pointer.
std::unique_ptr<Adaptor> get_adaptor(int flag)
{
if(flag == 0)
{
return std::make_unique<Adaptor_B>();
}
else if(flag == 1)
{
return std::make_unique<Adaptor_Y>();
}
else throw std::runtime_error("Invalid flag value");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.