0

我正在尝试一个有两个类和一个免费功能的基本东西。首先我有两个课程:

struct BASE{
    BASE(int a = 0):a_(a){};
    virtual ~BASE(){};
    virtual void foo(){std::cout << "BASE " << std::endl;}
    int a_;
};

struct DERIVED: public BASE{
    DERIVED():BASE(){};
    void foo(){std::cout << "DERIVED " << std::endl;}
};

然后我填写一个 std::vector (或 boost::ptr_vector)

std::vector<BASE* > vec;    
vec.push_back( new BASE(2));
vec.push_back( new DERIVED);

如果我调用我的函数 foo,则没有 pb 虚拟的东西效果很好,但是如果我创建两个自由函数:

void foo(BASE*   a, DERIVED*   b){
    std::cout << " mix base/derived " << std::endl;
}

void foo(BASE*   a, BASE*   b){
    std::cout << " full base " << std::endl;
}

如果我做

foo(vec[0], vec[1]); //failed

我会收到消息

full base

嗯,这是合乎逻辑的,因为我有 BASE* 的向量,但它是否存在以获得对我的自由函数的良好调用?我需要继承,所以我不能真正分离这两个类,因为我必须填满这个容器

此外,最后我的向量将被随机填充,所以我无法提前知道如何正确投射。

4

3 回答 3

2

获得解决方法的最简单(也是最快)的方法是再引入一个虚函数来唯一标识派生类(使用intenum值或typeid)。所以稍后你可能会调用它并意识到你在 , 后面有什么确切的派生类(或者可能是基类)BASE*,并对dynamic_cast那个类型做。

您没有提供有关您要解决的问题的详细信息...如果您想实施双重调度(或某种),请确保您已经对现有解决方案进行了完整的研究...

但通常,如果你需要dynamic_cast它意味着你的设计有问题(领域的 OOP 模型)......

于 2012-12-05T13:43:43.247 回答
0

就像你事先不知道你vec[i]是什么一样,编译器也不知道。函数重载解析是一个编译时过程,而多态性 - 运行时。

因此它调用void foo(BASE* a, BASE* b)版本。

换句话说,您想要做的事情是不可能的,除非您dynamic_cast尝试强制转换为每个可能的派生类。0如果对象类型错误,它将返回。

然而,许多人会争辩说,使用 dynamic_cast是糟糕设计的标志。而且它也很贵。

于 2012-12-05T13:39:01.153 回答
0

您需要为此进行动态调度,如下所示:

void foo(BASE *a, BASE *b) {
  if (DERIVED *bb = dynamic_cast<DERIVED*>(b)) {
    foo(a, bb);
  } else {
    std::cout << " full base " << std::endl;
  }
}

如果您不想使用 a dynamic_cast,您可以添加一个虚函数,BASE该函数将返回某种形式的类标识符(例如 an enum),在每个派生类中覆盖它,然后根据此函数的返回值分叉调用(连同static_cast)。

于 2012-12-05T13:43:09.950 回答