我来自Java,对C ++来说有点新鲜。 在Java中,我有可能这样做:link to code
我创建了一个抽象基类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();
}
但是我收到编译错误:
main.cpp:35:12: fatal error: variable type 'Mother' is an abstract class
Mother mother;
^
main.cpp:5:22: note: unimplemented pure virtual method 'bar' in 'Mother'
virtual void bar() = 0;
^
我错过了什么?
答案 0 :(得分:3)
与Java不同,C ++具有值语义而没有隐式指针:当您声明Mother mother;
时,您将获得Mother
的实际实例。不多也不少。除了你的情况,Mother
是抽象的:你不能有一个Mother
的实例!
稍后执行mother = child;
只会将孩子的Mother
部分分配到mother
。这称为“对象切片”,因为您希望复制的子部分也会被切掉。
要解决此问题,您需要使用指针或引用,它们都可以引用动态类型与其静态类型不同的对象(例如,实际为Mother
的{{1}})。我将使用最简单的拥有指针std::unique_ptr
:
Child0
请注意,我也已切换到动态分配:您的两个子实例是自动变量,这意味着它们在范围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();
}
的末尾死亡。 std::make_unique
构造一个具有动态生命周期的对象:它只会在持有它的{}
时死亡。
如另一个答案中所述,由于您的子对象将以多态方式被破坏,因此unique_ptr
的类型,Mother
的析构函数应该Mother
正确分派。< / p>
virtual
答案 1 :(得分:2)
您缺少object slicing陷阱,并且还有未定义的行为:分配
时 window.onbeforeunload = function(e){
gapi.auth2.getAuthInstance().signOut();
};
mother = child;
获得&#34;切片&#34;降至child
,删除任何多态行为。
如果您希望保留多态性,请使用指针:
mother
确保Mother *mother;
if(condition) {
mother = new Child0;
} else {
mother = new Child1;
}
mother->foo();
delete mother;
有一个虚拟析构函数。
请注意,您不能再使用内部作用域中的对象,因为一旦作用域结束,指针就会变为无效:
Mother