带继承的c ++向量

Ron*_*n E 7 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();
}
Run Code Online (Sandbox Code Playgroud)

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

$ ./test
Func -> call()
Func -> call()
Func -> call()
Run Code Online (Sandbox Code Playgroud)

有没有办法确保在这个实例中调用正确的虚函数?我是C++的新手,但最好的猜测是:

(*iter).call();
Run Code Online (Sandbox Code Playgroud)

它被投射到一个Func物体上.它是否正确?

And*_*zos 6

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

现在编写代码时,Foo和Bar实例被伪装(复制构造)到Func类型的实例中以适合向量.(原因是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();
}
Run Code Online (Sandbox Code Playgroud)

在上文中,引用计数指针用于隐含地共享向量中的Func的异类子类.(这种间接允许通过地址间接存储任意大小的Func子类.)

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

另一件需要关注的是完美转发和varadic模板.

更新:对于旧编译器:

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();
}
Run Code Online (Sandbox Code Playgroud)