简体   繁体   English

C ++虚函数实现?

[英]C++ Virtual function implementation?

If I have in C++: 如果我有C ++:

class A {
    private: virtual int myfunction(void) {return 1;}
}

class B: public A {
    private: virtual int myfunction(void) {return 2;}
}

Then if I remove virtual from the myfunction definition in class B , does that mean that if I had a class C based on class B , that I couldn't override the myfunction since it would be statically compiled? 然后,如果我从class Bmyfunction定义中删除virtual ,这是否意味着如果我有一个基于class B class C class B ,那么我无法覆盖myfunction因为它将被静态编译?

Also, I'm confused as to what happens when you switch around public, and private here. 此外,我很困惑当你在公共场所切换时会发生什么,而在这里私密。 If I change the definition of myfunction in class B to be public (and the one in class A remains private), is this some sort of grave error that I shouldn't do? 如果我将class Bmyfunction的定义更改为公共(并且class A那个仍然是私有的),这是否是我不应该做的某种严重错误? I think that virtual functions need to keep the same type so that's illegal, but please let know if that's wrong. 我认为虚拟功能需要保持相同的类型,这是非法的,但请告诉我是否错了。

Thanks! 谢谢!

The first definition with 'virtual' is the one that matters. “虚拟”的第一个定义是重要的。 That function from base is from then on virtual when derived from, which means you don't need 'virtual' for reimplemented virtual function calls. 从基础开始的那个函数从那时开始就是虚拟的,这意味着你不需要'virtual'来重新实现虚函数调用。 If a function signature in a base class is not virtual, but virtual in the derived classes, then the base class does not have polymorphic behaviour. 如果基类中的函数签名不是虚拟的,而是在派生类中是虚拟的,则基类不具有多态行为。

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
}

once a function is made virtual in a base class, it will be virtual for every other subclass. 一旦函数在基类中变为虚拟,它将对于每个其他子类都是虚拟的。

public, protected and private do not affect the virtual nature of functions. public,protected和private不会影响函数的虚拟性。

If You remove virtual from the myfunction definition in class B, 如果从B类中的myfunction定义中删除virtual

compiler will add this for You. 编译器会为你添加这个。 To fill out V-Table for polymorphic types. 为多态类型填写V-Table。

!!BUT!! !!但!!

You will only have access to public members of class A (class B: public A) 您只能访问A类公共成员(B类:公共A)

the definition : 定义 :

class B: private A
{

}

Will cause that all (even public) members of class A, will become private for class B. Simplifies You will not have an access to A public members. 将导致A类的所有(甚至公共)成员成为B级私人。简化您将无法访问A公共成员。

To workaround You can declare some friend: 解决方法您可以声明一些朋友:

class A
{
    private:
        friend class B;
}

More great info HERE . 更多信息在这里

The behavior of virtual is that it effects which method is called when you have a pointer of one type that points to an object of a subtype. virtual的行为是当你有一个指向子类型对象的指针时,它会影响调用哪个方法。 For example: 例如:

B* obj = new B;
A* base = obj;

What happens when you call obj->myfunction() depends on whether A declares myfunction to be virtual. 调用obj->myfunction()时会发生什么取决于A是否声明myfunction是虚拟的。 If it is not virtual, the reasoning is: we have a pointer of type A , so we call the function defined in A , and the result is 1. If A defines myfunction to be virtual, however, then a look-up is performed at run-time based on the type of the actual object, rather than the type of the pointer; 如果它不是虚拟的,那么推理是:我们有一个类型为A的指针,所以我们调用A定义的函数,结果为1.但是,如果Amyfunction定义为虚myfunction ,则执行查找在运行时基于实际对象的类型,而不是指针的类型; since the object is actually a B , the implementation defined in B is used and the result is 2. 由于对象实际上是B ,因此使用B定义的实现,结果为2。

Further information can be found in the C++ FAQ Lite section on virtual functions . 有关虚拟功能的C ++ FAQ Lite部分可以找到更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM