[英]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.