如果我使用C ++:
class A {
private: virtual int myfunction(void) {return 1;}
}
class B: public A {
private: virtual int myfunction(void) {return 2;}
}
然后,如果我从virtual
中的myfunction
定义中移除class B
,那是否意味着如果我基于class C
有class B
,那我就是无法覆盖myfunction
,因为它将被静态编译?
另外,我很困惑当你在公共场所切换时会发生什么,而在这里是私密的。如果我将myfunction
中的class B
的定义更改为公开(且class A
中的那个仍为私有),这是否是我不应该做的某种严重错误?我认为虚拟功能需要保持相同的类型,这是非法的,但请告知我是否错了。
谢谢!
答案 0 :(得分:17)
“虚拟”的第一个定义是重要的。从基础开始的那个函数从那时开始就是虚拟的,这意味着你不需要'virtual'来重新实现虚函数调用。如果基类中的函数签名不是虚拟的,而是派生类中的虚函数,则基类不具有多态行为。
class Base
{
public:
void func(void){ printf("foo\n"); }
};
class Derived1 : public Base
{
public:
virtual void func(){ printf("bar\n"); }
};
class Derived2 : public Derived1
{
public:
/* reimplement func(), no need for 'virtual' keyword
because Derived1::func is already virtual */
void func(){ printf("baz\n"); }
};
int main()
{
Base* b = new Derived1;
Derived1* d = new Derived2;
b->func(); //prints foo - not polymorphic
d->func(); //prints baz - polymorphic
}
答案 1 :(得分:7)
一旦函数在基类中成为虚函数,它对于每个其他子类都是虚拟的。
public,protected和private不会影响函数的虚拟性。
答案 2 :(得分:1)
如果您从B类的virtual
定义中移除myfunction
,
编译器会为你添加这个。为多态类型填写V-Table。
!! BUT !!
您只能访问A类公众成员(B类:公共A)
定义:
class B: private A
{
}
将导致A类的所有(甚至是公开的)成员成为B类的私人成员。 简化您将无法访问A公共成员。
解决方法您可以声明一些朋友:
class A
{
private:
friend class B;
}
更多精彩信息HERE。
答案 3 :(得分:0)
virtual
的行为是,当你有一个指向一个子类型的对象的指针时,它会影响调用哪个方法。例如:
B* obj = new B;
A* base = obj;
致电obj->myfunction()
时会发生什么情况取决于A
是否宣布myfunction
是虚拟的。如果它不是虚拟的,那么推理是:我们有一个A
类型的指针,所以我们调用A
中定义的函数,结果为1.如果A
定义{{但是,如果是虚拟的,则在运行时根据实际对象的类型而不是指针的类型执行查找;由于对象实际上是myfunction
,因此使用B
中定义的实现,结果为2.