C++ 两个不同类的运行时多态性
我有两个类C++ 两个不同类的运行时多态性,c++,c++11,polymorphism,C++,C++11,Polymorphism,我有两个类B和Y,我不能根据需要更改或编辑它们。它们有做相同事情的函数,但名称不同 我希望有一个公共接口,在运行时根据下面代码中描述的某个输入变量选择类。我不确定我应该使用哪种设计模式。如何创建WrapperYB类,该类根据创建的对象选择Y::show或B::show class A { public: A() {} virtual ~A(); virtual void show() { cout << "show A" << endl;} };
B
和Y
,我不能根据需要更改或编辑它们。它们有做相同事情的函数,但名称不同
我希望有一个公共接口,在运行时根据下面代码中描述的某个输入变量选择类。我不确定我应该使用哪种设计模式。如何创建WrapperYB
类,该类根据创建的对象选择Y::show
或B::show
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
}
A类
{
公众:
A(){}
虚拟~A();
虚拟void show(){cout我建议:
#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
}
#包括
使用名称空间std;
甲级
{
公众:
A(){}
虚拟~A(){}
虚拟虚空显示(){cout如果您的编译器支持C++17标准,您可以使用尝试此解决方案。这与@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;
};
#包括
#包括
#包括
类包装器{
公众:
使用variant_type=std::variant;
模板
WrapperYB(Args&&…Args):m_变量(std::forward)
您可以通过让包装器包含一个std::unique\u ptr
或std::unique\u ptr
来概括包装器。您可以使用一个标准的虚拟分派方法,为每个需要的对象类型使用一个抽象的基本适配器类和子类。使用工厂方法创建对象
#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");
}
#包括
//预定义结构Y,B
结构
{
Y(){}
~Y(){}
void show(){}
};
结构B
{
B(){}
~B(){}
无效显示(){}
};
//抽象适配器基类。
结构适配器
{
虚拟void show()=0;
};
//适配器的子类,用于要包装的每种类型的对象。
结构适配器_Y:适配器
{
适配器_Y():Y(){}
void show()覆盖
{
y、 show();
}
私人:
Y;
};
结构适配器\u B:适配器
{
适配器_B():B(){}
void show()覆盖
{
b、 显示();
}
私人:
B B;
};
//工厂方法构造适当的对象并返回指针。
std::唯一的ptr get_适配器(int标志)
{
如果(标志==0)
{
返回std::make_unique();
}
else if(标志==1)
{
返回std::make_unique();
}
else抛出std::runtime_错误(“无效标志值”);
}
谢谢Nicolas的帮助。这就是我一直在寻找的。谢谢你的想法。我在项目中使用Qt,但与C++17不兼容。我想我可以用QVariant
编写类似的代码。我还没有尝试过,但肯定尝试过。你在WrapperYB
的构造函数中缺少包扩展(std::forward(args)…
)。@Zereges是的。我还设法在ShowImpl
成员中将const
放在了错误的位置。