[英]How to recover an interface through crosscast
一等座
class Io_obj
{
public:
virtual Io_obj* clone() const=0;
virtual ~Io_obj(){}
};
一阶派生类
template<typename T>
class Io : public Io_obj,T
{
public:
Io(){}
Io(string& s){cout << s << '\n';}
Io* clone() const override {return new Io{*this};}
static Io* new_io(string& s){return new Io{s};}
};
二等座
class Shape
{
public:
virtual void draw() const=0;
virtual ~Shape(){}
};
二次派生类
class Circle : public Shape
{
public:
Circle(){}
Circle(string& s){cout << s << '\n';}
void draw() const override{cout << "draw circle\n";}
};
class Triangle : public Shape
{
public:
Triangle(){}
Triangle(string& s){cout << s << '\n';}
void draw() const override {cout << "draw triangle";}
};
主要功能
using io_circle = Io<Circle>;
using io_triangle = Io<Triangle>;
using Pf = function<Io_obj*(string&)>;
map<string,Pf> io_map{{"circle",&io_circle::new_io},{"triangle",&io_triangle::new_io}};
Io_obj* get_obj(string& s){
if(auto f=io_map[s]) return f(s);
throw runtime_error{"error: wrong type"};
}
int main(){
vector<string> vs{"circle","triangle","square"};
for(auto x:vs){
unique_ptr<Io_obj> my_obj{get_obj(x)};
if(auto sp=dynamic_cast<Shape*>(my_obj.get())){
sp->draw();
}else{
throw runtime_error{"error: bad cast"};
}
}
return 0;
}
动态投射失败。 看来由unique_ptr<Io_obj> my_obj{get_obj(x)}
创建的对象的类型为Io_obj
,它没有成员函数draw()
。 如何使其运作?
Bjarne Stroustrup的代码:C ++编程语言Ch22.2.4
要解决此问题,请更改:
template<typename T>
class Io : public Io_obj, T
至:
template<typename T>
class Io : public Io_obj, public T
必须为每种基本类型分别编写访问说明符。 在您的情况下,第二个派生是private
,因为这是默认模式。
如果它们通过公共继承创建的is-a关系连接, dynamic_cast<>
会将Io<T>
dynamic_cast<>
转换为T
在私有的情况下, dynamic_cast<>
将不起作用,因为Io<T>
不是 T
(私有继承会创建称为“根据...实现的”关系 )。
测试: http : //coliru.stacked-crooked.com/a/130c7768fb5b501d
当然,此代码还会抛出std::runtime_error
,因为您尚未为square
类型注册“ factory”,但我想您已经知道这一点了:)
可能有些参考( 18.5.2 - dynamic_cast<T>(v)
):
否则,将应用运行时检查以查看
v
指向或引用的对象是否可以转换为T
指向或引用的类型。运行时检查在逻辑上执行如下:
如果,在最派生对象指向的(简称)至
v
,V点(指)到的公共基类子对象T
对象,并且如果只有一个类型的对象T
从子对象衍生指出(简称)到v
的结果是指向该T
对象的指针(一个左值引用)。否则,如果
v
指向(引用)最派生对象的公共基类子对象,并且最派生对象的类型具有类型T
的基类(即明确且公共的) ,则结果为指针(表示左值)到最派生对象的T
子对象。否则,运行时检查将失败。
转换为指针类型失败的值是所需结果类型的空指针值。 转换为引用类型失败会抛出
bad_cast
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.