具有继承性的 C++ vector

标签 c++ inheritance vector

引用代码:

#include <vector>
#include <iostream>

class Func {
public:
    virtual void call() {
        std::cout<< "Func -> call()" << std::endl;
    }
};

class Foo : public Func {
public:
    void call() {
        std::cout<< "Foo -> call()" << std::endl;
    }
};

class Bar : public Func {
public:
    void call() {
        std::cout<< "Bar -> call()" << std::endl;
    }
};

int main(int argc, char** argv) {
    std::vector<Func> functors;

    functors.push_back( Func() );
    functors.push_back( Foo() );
    functors.push_back( Bar() );

    std::vector<Func>::iterator iter;
    for (iter = functors.begin(); iter != functors.end(); ++iter)
        (*iter).call();
}

运行该代码时,它会在我的计算机上产生以下输出:

$ ./test
Func -> call()
Func -> call()
Func -> call()

是否有任何方法可以确保在这种情况下调用正确的虚函数?我是 C++ 的新手,但我最好的猜测是:

(*iter).call();

它被转换为一个 Func 对象。这是正确的吗?

最佳答案

您应该使用 shared_ptr 或 unique_ptr 来保存多态类型集合的元素。

随着您现在编写代码,Foo 和 Bar 实例被强制(复制构造)为 Func 类型的实例以适合 vector 。 (原因是 vector 为了性能立即按固定大小的值存储其元素,但是多态子类具有任意大的大小,在编译时未知,因此它只能存储基类。)

这样更好:

int main(int argc, char** argv) {
    vector<shared_ptr<Func>> functors;

    functors.push_back( make_shared<Func>() );
    functors.push_back( make_shared<Foo>() );
    functors.push_back( make_shared<Bar>() );

    for (auto functor : functors)
        functor->call();
}

在上面,引用计数指针用于隐式共享 vector 中 Func 的异构子类。 (这种间接允许通过地址间接存储任意大小的 Func 子类。)

另外,您可能想看看 std::function 和 std::bind,而不是滚动您自己的仿函数类型。

另一件要看的事情是完美转发和可变参数模板。

更新:对于旧的编译器:

int main(int argc, char** argv) {
    vector<std::tr1::shared_ptr<Func> > functors;

    functors.push_back( std::tr1::make_shared<Func>() );
    functors.push_back( std::tr1::make_shared<Foo>() );
    functors.push_back( std::tr1::make_shared<Bar>() );

    for (size_t i = 0; i < functors.size(); ++i)
        functors[i]->call();
}

关于具有继承性的 C++ vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10154977/

相关文章:

构造函数中的 C++ 单例

python - 同时使用父属性和重写子属性的继承

java - Guice 子模块阻止继承绑定(bind)

python - 使用 Python 对 2 个数组中包含的向量进行元素级叉积

c++ - 对象杀死自身问题

java - 使用java通过usb/RS232转换器发送数据

c++ - 在 C++ (Qt) 中设置具有非本地 IP 地址的服务器

c++ - C++ 中的继承和模板 : Why doesn't the following piece of code compile?

c++ - std::vector 作为 MPI 非阻塞函数的输入缓冲区

C++ 字符串、标点符号、数组