Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
将派生的存储在基赋值中,然后调用基函数 我是java的,有点C++的。 在Java中,我可以这样做:_C++_Oop_Abstract Class_Virtual Functions - Fatal编程技术网

将派生的存储在基赋值中,然后调用基函数 我是java的,有点C++的。 在Java中,我可以这样做:

将派生的存储在基赋值中,然后调用基函数 我是java的,有点C++的。 在Java中,我可以这样做:,c++,oop,abstract-class,virtual-functions,C++,Oop,Abstract Class,Virtual Functions,我创建了一个抽象基类Mother,在同一基类的公共函数中使用了一个纯虚函数 我试过这个: class Mother { private: virtual void bar() = 0; public: void foo(); }; void Mother::foo() { // ... some code bar(); } class Child0: public Mother { private: vo

我创建了一个抽象基类
Mother
,在同一基类的公共函数中使用了一个纯虚函数

我试过这个:

class Mother {
    private:
        virtual void bar() = 0;
    public:
        void foo();
};

void Mother::foo() {
    // ... some code
    bar();
}

class Child0: public Mother {
    private:
        void bar();
};

void Child0::bar() {
    std::cout << "Child0" << std::endl;
}

class Child1: public Mother {
    private:
        void bar();
};

void Child1::bar() {
    std::cout << "Child1" << std::endl;
}

// main code
int main() {
    Mother mother;
    if(condition) {
        Child0 child;
        mother = child;
    } else {
        Child1 child;
        mother = child;
    }
    mother.foo();
}
我遗漏了什么?

您遗漏了陷阱,并且还有未定义的行为:当您分配

mother = child;
child
被“切片”到
mother
,任何多态行为都被删除

如果希望保留多态性,请使用指针:

Mother *mother;
if(condition) {
    mother = new Child0;
} else {
    mother = new Child1;
}
mother->foo();
delete mother;
确保
Mother
具有虚拟析构函数

请注意,您不能再使用内部作用域中的对象,因为一旦作用域结束,指针将变得无效:

// Do not do this!
Mother *mother;
if(condition) {
    Child0 child;
    mother = &child;
}
mother->foo(); // <<<=== This is undefined behavior
//不要这样做!
母亲*母亲;
如果(条件){
儿童0儿童;
母亲=&孩子;
}

母亲->福();// 与Java不同,C++具有值语义,并且没有隐式指针:当您声明
母亲时
您将获得一个实际的
Mother
实例。不多也不少。除了在您的情况下,
Mother
是抽象的:您不能有
Mother
的实例
母亲=孩子
以后只需将孩子的
母亲
部分分配给
母亲
。这称为“对象切片”,因为您希望复制的子部分也被切掉

要解决这个问题,您需要使用指针或引用,它们都可以引用动态类型不同于静态类型的对象(例如,
Mother
实际上是
Child0
)。我将使用最简单的指针:


“它不工作”不是有效的问题描述。@LightnessRacesinOrbit“我来自Java”是;)@昆汀:印尼没什么问题@昆廷:我可能会,但我认为这是一个边缘,不建议在没有进一步意见的情况下将我的意见作为有用的指南:)@Quentin:当然,在您自己的系统上复制错误信息后,您必须用新的行号(以及其他任何更改)更新/替换错误信息。它开始变得有点粘,因为没有太多的收获。非常感谢你的答案,不能把两个答案作为“接受”,所以我很难过:/谢谢你的快速回答,从一种语言到另一种语言是复杂的…:)@不客气!java阻止你看到C++所需要的大部分事情,但是一旦你得到了C++,你就很有趣了:
// Do not do this!
Mother *mother;
if(condition) {
    Child0 child;
    mother = &child;
}
mother->foo(); // <<<=== This is undefined behavior
int main() {
    std::unique_ptr<Mother> mother;

    if(condition) {
        mother = std::make_unique<Child0>();
    } else {
        mother = std::make_unique<Child1>();
    }

    // At this point, *mother is of static type Mother,
    // but of dynamic type Child0 or Child1.

    mother->foo();
}
class Mother {
    // ...
public:
    virtual ~Mother() = default;
};