当我在Visual Studio 2010中运行以下C++代码时,如果任何派生类函数被声明为虚函数,程序将在变量删除处卡住。有人能解释一下吗?
更多信息:
我知道要调用b::fn1和类b的析构函数,需要在基类即a类中声明它们为虚函数。但是如果我不这样做,也不声明b类(也不是a类)中的任何函数为虚函数,则应该调用a的fn1和析构函数,并且这确实发生了。但是当我将b类(但不是a类)的任何成员声明为虚函数,无论是新成员还是重载成员,使用VS2010编译时会挂起,使用linux上的gcc4.4.4编译时则会出现错误。它应该调用其中一个析构函数并正常工作,但我无法理解程序崩溃的原因。
进一步地,在使用Visual Studio 2010中的Intellitrace时,我试图在挂起代码的位置中断,会收到以下消息:
该进程似乎已死锁(或未运行任何用户模式代码)。 所有线程都已停止。
void testInheritance()
{
class a
{
public :
char x;
void fn1()
{
std::cout<<"\n In Class A Function 1 : "<<x;
}
virtual void fn2()
{
std::cout<<"\n In Class A Function 2 : "<<x;
}
a()
{
x='A';
std::cout<<"\n In A() : "<<x;
}
~a()
{
std::cout<<"\n In ~A : "<<x;
}
};
class b: public a
{
public :
char y;
virtual void fn1()
{
std::cout<<"\n In Class B Function 1 : "<<y;
}
void fn3()
{
std::cout<<"\n In Class B Function 3 : "<<y;
}
b()
{
y='B';
std::cout<<"\n In B() : "<<y;
}
~b()
{
std::cout<<"\n In ~B : "<<y;
}
};
a* var = new b();
delete var;
}
更多信息:
我知道要调用b::fn1和类b的析构函数,需要在基类即a类中声明它们为虚函数。但是如果我不这样做,也不声明b类(也不是a类)中的任何函数为虚函数,则应该调用a的fn1和析构函数,并且这确实发生了。但是当我将b类(但不是a类)的任何成员声明为虚函数,无论是新成员还是重载成员,使用VS2010编译时会挂起,使用linux上的gcc4.4.4编译时则会出现错误。它应该调用其中一个析构函数并正常工作,但我无法理解程序崩溃的原因。
进一步地,在使用Visual Studio 2010中的Intellitrace时,我试图在挂起代码的位置中断,会收到以下消息:
该进程似乎已死锁(或未运行任何用户模式代码)。 所有线程都已停止。
a
的fn1
声明之前没有放置virtual
关键字,所以a* bb = new b; bb->fn1();
将调用a::fn1
。 - Matthieu M.