我正在修改代码,即祖父类是纯虚拟的,包括函数XYZ的纯虚拟版本;然后,父类将XYS声明为虚拟,并且它具有实现。然后子类将XYZ声明为一个常规函数,其实现与parent1 9的实现不同,其本身就让我感到困惑)。当我从另一个对象调用函数XYZ时,执行哪个实现?父母一个还是孩子一个?感谢
答案 0 :(得分:5)
当我从另一个对象调用函数XYZ时,执行哪个实现?父母一个或一个孩子?
struct A {
virtual void f() = 0;
};
struct B : A {
virtual void f() { cout << "B::f\n"; }
};
struct C : B {
virtual void f() { cout << "C::f\n"; }
};
int main() {
C().f();
return 0;
}
答案 1 :(得分:3)
纯虚函数不需要定义(与虚函数相对),它们使它们的类抽象化。抽象类不能创建从中创建的对象,除非它们充当基类对象。
您的混淆似乎围绕virtual
关键字的存在与否。如果函数在基类中声明为virtual
,则派生类的函数(无论是否放置virtual
关键字)如果具有相同的名称,将自动变为virtual
,参数类型和常量。
因此,如果您在实际指向grandparent*
对象的parent*
或child
上调用XYZ,则会执行child
对象的XYZ。
答案 2 :(得分:2)
纯虚函数只意味着不能实例化具有纯虚函数的类。一旦父类覆盖它,它就会变成一个普通的虚函数。一旦函数在基类中被声明为虚拟,它就总是虚拟的,无论继承类是否将其定义为虚拟。
编辑:这意味着调用它只是像任何其他函数一样调用虚函数 - 也就是说,将调用派生类最多的实现。
答案 3 :(得分:0)
纯虚函数通常没有实现,并创建了类的“抽象性”。
编译器不允许您创建抽象类的实例。除非所有继承的纯虚函数都已实现(并且不添加任何新函数),否则从该类派生的任何类都将保持抽象。这样的一个类叫做具体。
请注意,可以为纯虚函数提供实现(尽管出于语法原因无法内联)。此外,您可以拥有纯虚拟析构函数,然后必须为其提供实现(即使它是空的)。
通过在末尾添加= 0来表示纯虚函数:
virtual void foo(); // not pure
virtual void bar() = 0; // pure virtual
答案 4 :(得分:0)
class sample
{
public:
virtual void fun(); //virtual function
virtual void sun()=0; //pure virtual function
};
通过分配0
来声明纯虚函数,如上所述。提供纯虚拟功能的定义是可选,而为虚拟功能提供定义强制,否则不编译。此外,您无法创建甚至定义单个纯虚拟函数的类的实例。
答案 5 :(得分:0)
虚函数是可以在派生类中重写的函数。
纯虚函数是一个完全没有实现的函数,因此在派生类中重写必须。
除非使用自己的实现覆盖任何纯虚函数,否则无法使用纯虚函数或从其派生的类创建类的实例。
答案 6 :(得分:0)
对于虚函数,如果在子类的对象上调用xyz,始终将执行xyz(Child::xyz()
)的子版本。
非虚拟重写方法不会出现这种情况。然后,如果你有一个指针Parent* ptr = &child
,ptr>xyz()
实际上会执行Parent::xyz()
。但在你的情况下它是Child::xyz()
。这就是您使用virtual
关键字的原因。