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
我不明白:
- virtual ~abc函数是怎么调用的?
- 为什么程序结束时是运行?
- 函数的目的是什么?
~abc
是 abc
的析构函数。它是一个在不再需要对象时销毁对象的函数。
在程序结束时,每个对象都被销毁,因为程序调用了每个析构函数。您定义了析构函数来打印这些行,它确实如此。
另外,树中的每个对象都继承自abc
,所以它们都继承了析构函数。您声明了两个对象,ghi
和 jkl
。它们必须在程序结束时被销毁,因此它们调用了从 abc
继承的析构函数。
析构函数用于以自定义方式销毁对象,以免内存泄漏。例如,如果您的对象中有一个指向其他内容的指针,为了安全起见,您可以将该指针设置为 nullptr
。
请注意,每个对象都有一个默认析构函数,但默认情况下它不打印任何内容,这就是您不知道它们存在的原因。
虚拟继承不是您所做的。您对具有虚函数的 类 进行了静态继承。
你的疑惑与虚函数无关。
- 全局变量:
myVar
和myVar2
是全局的:在进入main之前创建,退出main之后销毁。析构函数是或不是虚拟的事实 - 在这种情况下 - 是......无关紧要。
- 构造函数按照成员和派生的顺序被调用。析构函数的调用顺序与构造函数相反。
abd
在 def
和 ghi
的销毁链中被调用。你看不到它,因为你没有使 ghi
和 def
析构函数冗长。
通过虚函数实现的运行时多态性需要指向基的指针或引用。
如果您直接使用值变量,则不会使用虚拟分派。
#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
我不明白:
- virtual ~abc函数是怎么调用的?
- 为什么程序结束时是运行?
- 函数的目的是什么?
~abc
是 abc
的析构函数。它是一个在不再需要对象时销毁对象的函数。
在程序结束时,每个对象都被销毁,因为程序调用了每个析构函数。您定义了析构函数来打印这些行,它确实如此。
另外,树中的每个对象都继承自abc
,所以它们都继承了析构函数。您声明了两个对象,ghi
和 jkl
。它们必须在程序结束时被销毁,因此它们调用了从 abc
继承的析构函数。
析构函数用于以自定义方式销毁对象,以免内存泄漏。例如,如果您的对象中有一个指向其他内容的指针,为了安全起见,您可以将该指针设置为 nullptr
。
请注意,每个对象都有一个默认析构函数,但默认情况下它不打印任何内容,这就是您不知道它们存在的原因。
虚拟继承不是您所做的。您对具有虚函数的 类 进行了静态继承。
你的疑惑与虚函数无关。
- 全局变量:
myVar
和myVar2
是全局的:在进入main之前创建,退出main之后销毁。析构函数是或不是虚拟的事实 - 在这种情况下 - 是......无关紧要。 - 构造函数按照成员和派生的顺序被调用。析构函数的调用顺序与构造函数相反。
abd
在def
和ghi
的销毁链中被调用。你看不到它,因为你没有使ghi
和def
析构函数冗长。
通过虚函数实现的运行时多态性需要指向基的指针或引用。
如果您直接使用值变量,则不会使用虚拟分派。