如何通过交叉广播恢复界面

时间:2015-11-08 10:31:32

标签: c++ interface polymorphism dynamic-cast

第一个基类

irb(main):012:0> Robot.new.object_id == Robot.new.object_id
=> false

第一个派生类

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。如何使它工作?

Bjarne Stroustrup的代码:C ++编程语言Ch22.2.4

1 个答案:

答案 0 :(得分:3)

要解决此问题,请更改:

public static void main(String[] args){
    int rows = 6;
    int[][] triangle = new int[rows][rows];

    for (int i = 1 ; i <= rows  ; i++){
        for (int j = 0 ; j < i ; j++){
            if (j == 0) triangle[i-1][j] = 1;
            else triangle[i-1][j] = triangle[i-2][j-1] + triangle[i-2][j];
            System.out.print(triangle[i-1][j] + " ");
        }
        System.out.println();
    }
}

为:

template<typename T>
class Io : public Io_obj, T

必须为每种基本类型单独编写访问说明符。在您的情况下,二次推导是template<typename T> class Io : public Io_obj, public T ,因为这是默认模式。

privatedynamic_cast<>转换为Io<T>,如果它们与 is-a 关系相关联,该关系由公共继承创建。如果是私有的,T将无效,因为dynamic_cast<> 不是 Io<T>(私有继承会创建名为的关系“,以”< / em>的)。

测试:http://coliru.stacked-crooked.com/a/130c7768fb5b501d

当然这段代码也会抛出T,因为你没有为std::runtime_error类型注册“factory”,但我想你已经知道了这一点:)

一些参考,也许( 18.5.2 - square):

  

否则,将应用运行时检查以查看对象是否指向或   由dynamic_cast<T>(v)引用的可以转换为指向或引用的类型   v

     

运行时检查按逻辑执行如下:

     

如果在由T指向(引用)的最派生对象中,则为v   (指)v对象的 public 基类子对象,以及if   只有一个T类型的对象派生自指向的子对象   (引用)T,结果是一个指针(左值引用)   那个v对象。

     

否则,如果T指向(指向)公共基类   最派生对象的子对象,以及最多的类型   派生对象有一个类型为v的基类,它是明确的    public ,结果是指向最派生对象的T子对象的指针(左值引用)。

     

否则,运行时检查失败。

     

失败的强制转换为指针类型的值是空指针值   所需结果类型。抛出失败的强制转换为引用类型   T