C++虚拟继承

C++ Virtual Inheritance

#include <stdio.h>


class abc{
    public:
        abc     *next;

    protected:
        int             flags;
        const char *    name;
        const char *    comments;

    public:
        abc(const char *name, const char *comments, int flags);

        virtual ~abc() {
            printf("\nReached at virtual ~abc\n");
            printf("Returning from at virtual ~abc\n");
        }   
};

class def: public abc{
    public:
        def (const char *myname, const char *mycomments, 
              int myflags): abc(myname, mycomments, myflags)
        {
            printf("\nreached at def\n");
            printf("name=%s; comments=%s\n", myname, mycomments);
            printf("Returning from def\n");
        }
};

class ghi: public def{
    public:
        ghi(const char *myname2, const char *mycomments2, 
            int myflags2): def(myname2, mycomments2, myflags2)
        {
            printf("\nreached at ghi\n");
            printf("name=%s; comments=%s\n", myname2, mycomments2);
            printf("Returning from ghi\n");
        }
};

class jkl: public def{
    public:
        jkl(const char *myname2, const char *mycomments2, 
            int myflags2): def(myname2, mycomments2, myflags2)
        {
            printf("\nreached at ghi\n");
            printf("name=%s; comments=%s\n", myname2, mycomments2);
            printf("Returning from ghi\n");
        }
};

ghi myVar("myVar", "Testing it", 0);
jkl myVar2("myVar2", "Testing it Again", 0);

abc::abc(const char *name, const char *comments, int flags) : next(0){
    printf("\nreached at abc::abc\n");
    printf("name=%s; comments=%s\n", name, comments);
    printf("Returning from abc:abc\n");
}



int main(void){
    printf("\nrunning main function\n");
    printf("ending main function\n");
    return 0;
}

输出:

reached at abc::abc
name=myVar; comments=Testing it
Returning from abc:abc

reached at def
name=myVar; comments=Testing it
Returning from def

reached at ghi
name=myVar; comments=Testing it
Returning from ghi

reached at abc::abc
name=myVar2; comments=Testing it Again
Returning from abc:abc

reached at def
name=myVar2; comments=Testing it Again
Returning from def

reached at ghi
name=myVar2; comments=Testing it Again
Returning from ghi

running main function
ending main function

Reached at virtual ~abc
Returning from at virtual ~abc

Reached at virtual ~abc
Returning from at virtual ~abc

我不明白:

~abcabc 的析构函数。它是一个在不再需要对象时销毁对象的函数。

在程序结束时,每个对象都被销毁,因为程序调用了每个析构函数。您定义了析构函数来打印这些行,它确实如此。

另外,树中的每个对象都继承自abc,所以它们都继承了析构函数。您声明了两个对象,ghijkl。它们必须在程序结束时被销毁,因此它们调用了从 abc 继承的析构函数。

析构函数用于以自定义方式销毁对象,以免内存泄漏。例如,如果您的对象中有一个指向其他内容的指针,为了安全起见,您可以将该指针设置为 nullptr

请注意,每个对象都有一个默认析构函数,但默认情况下它不打印任何内容,这就是您不知道它们存在的原因。

虚拟继承不是您所做的。您对具有虚函数的 类 进行了静态继承。

你的疑惑与虚函数无关。

  1. 全局变量:myVarmyVar2是全局的:在进入main之前创建,退出main之后销毁。析构函数是或不是虚拟的事实 - 在这种情况下 - 是......无关紧要。
  2. 构造函数按照成员和派生的顺序被调用。析构函数的调用顺序与构造函数相反。 abddefghi 的销毁链中被调用。你看不到它,因为你没有使 ghidef 析构函数冗长。

通过虚函数实现的运行时多态性需要指向基的指针或引用。

如果您直接使用值变量,则不会使用虚拟分派。