Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确获得虚拟继承?_C++_C++11_Abstract Class_Virtual Inheritance - Fatal编程技术网

C++ 如何正确获得虚拟继承?

C++ 如何正确获得虚拟继承?,c++,c++11,abstract-class,virtual-inheritance,C++,C++11,Abstract Class,Virtual Inheritance,在下面的例子中,我有我的父类和两个子类。任一子对象都存储在父对象的向量中。在向量上循环,我只看到来自父类的方法调用 如何正确地获得方法定义和vtables,以及如何避免切片效果。我已经在Python上做了很长时间了,类似这样的东西可以工作 #include <iostream> #include <vector> using namespace std; class A{ public: virtual string print(){ret

在下面的例子中,我有我的父类和两个子类。任一子对象都存储在父对象的向量中。在向量上循环,我只看到来自父类的方法调用

如何正确地获得方法定义和vtables,以及如何避免切片效果。我已经在Python上做了很长时间了,类似这样的东西可以工作

#include <iostream>
#include <vector>


using namespace std;

class A{
    public:

        virtual string print(){return string("A");};
};

class B: public A{
    virtual string print() final {return string("B");};
};

class C: public A{
    virtual string print() final {return string("C");};
};

int main()
{

   vector<A> v;
   v.push_back(B());
   v.push_back(C());

   for(auto x : v){
       cout << x.print() << endl;
   }

}

让我们看看您的代码:

vector<A> v;
v.push_back(B());
v.push_back(C());
既然向量使用了
std::unique_ptr
,那么在向量上循环时需要使用
&

for(auto& x : v) {
    std::cout << x->print() << std::endl;
}
用于(自动和x:v){
std::cout print()
任一子对象都存储在父对象的向量中

不可以。父对象的向量只能存储父对象。父对象不是子对象

在向量上循环,我只看到来自父类的方法调用

这是因为向量包含父对象

如何正确地获取方法定义和vtables

成员函数定义或vtables没有问题

以及如何避免切片效应

通过不将基子对象从派生对象上切分,可以避免切分效果。动态多态性只能通过间接方式实现。使用指针(或引用)可以指向基子对象,该基子对象可能是不同派生对象的基子对象。示例:

B b;
C c;
A* a;

a = &b;
a->print(); // dynamic dispatch invokes B::print
a = &c;
a->print(); // dynamic dispatch invokes C::print

A sliced = b;
sliced.print(); // static dispatch invokes A::print
                // sliced is an individual object that is not
                // base sub object of another

你的风格不常见,在
main
中定义类。什么参考书提到了这种风格?非常有用的SO文章。风格-我刚刚将示例拼凑在一起,为风格进行编辑…请注意,没有错误的切片效果:临时
B
C
对象在创建时被切片(或者,正确地说,他们的
A
基类)被复制/移动到向量中。@1201程序谢谢,修复了。由于某种原因,我错误地记住了“切片”的定义我还以为这意味着什么。谢谢你详尽的回答。我会在有时间的时候尝试。我不完全理解副本的最后一段,而且
代码不会编译
。你能详细说明一下,请链接到某个地方吗?非常感谢!@ElDude你以前用过吗?这是一个代表“唯一所有权”的“智能指针”资源与
std::unique\u ptr
的生存期相关联,当其析构函数运行时,它会清理资源。因此,复制
std::unique\u ptr
是无效的操作,因为两个
std::unique\u ptr
将负责相同的资源。因此,
std::unique\u ptr
's copy构造函数是
delete
d。您只能使用移动构造函数来转移所有权。@ElDude您可以使用
auto
,但您需要将
放在它后面,就像
auto&
。这是因为
auto
没有指定类型是引用。
auto
的完整类型是de>std::unique\u ptr
,您想要的类型是
std::unique\u ptr&
for(auto& x : v) {
    std::cout << x->print() << std::endl;
}
B b;
C c;
A* a;

a = &b;
a->print(); // dynamic dispatch invokes B::print
a = &c;
a->print(); // dynamic dispatch invokes C::print

A sliced = b;
sliced.print(); // static dispatch invokes A::print
                // sliced is an individual object that is not
                // base sub object of another