导航
  • 主页
  • VC综合技术
  • 互联网技术
  • MFC AppLauncher
  • .NET 技术
  • 界面
  • 进程
  • 算法
  • 硬件/系统
  • 数据库
  • VC++技术资源

今天去应聘,考得都是郁闷的题目,心情不好,散分

SunsBird 2004-04-07 03:39:23
(1) 析构函数为什么一般不调用虚拟函数?
(2) 析构函数调用虚拟函数有什么作用?

哪位神仙,帮我说说,用了好几年,他奶奶的,我从不用过这些啊!难道做项目要用这种偏知识,我敢保证,刚出校门的小兄弟在这方面强啊!!
...全文
24 点赞 收藏 163
写回复
163 条回复
切换为时间正序
请发表友善的回复…
发表回复
mzg3 2004-04-23
haha
回复
stray1718 2004-04-23
这种公司不去也罢
幸好没去
不过说回来了,还是怪自己基础没学好
回复
sonyg 2004-04-23
一帮牛人!建议斑竹把这个收到珍藏中去
一帮牛人!建议斑竹把这个收到珍藏中去
一帮牛人!建议斑竹把这个收到珍藏中去
一帮牛人!建议斑竹把这个收到珍藏中去
一帮牛人!建议斑竹把这个收到珍藏中去
一帮牛人!建议斑竹把这个收到珍藏中去
一帮牛人!建议斑竹把这个收到珍藏中去
回复
sonyg 2004-04-23
一帮牛人!建议斑竹把这个收到珍藏中去
回复
kuku411 2004-04-23
我也要分
回复
暗黑帝国 2004-04-23
用来释放派生类的资源的吧,否则有可能不能正确释放调派生类申请的资源
回复
GSK168 2004-04-10
同情你哥们!
回复
kuangjingbo 2004-04-10
支持kevin_wang(kevin神)的观点
回复
PDD123 2004-04-10
我要分~~~谢谢~~
回复
DarkTemplar1999 2004-04-09
to:yuanbocsut(打盹的神仙)
在<<深入浅出MFC>>第3章MFC6大关键技术仿真:RTTI执行期类识别中有精辟论证.
对不起,妙手回春兄,我错了,不是不调用子类的虚拟析构函数,而是虚拟析构函数出发基类的析构函数,本身不执行而已,虚拟函数表里面还是有它的,执行效率一样快不了多少.
5555,我认错,我浅薄.
我有<<Effective c++>>中文版电子档,你要不要.给个邮箱发给你
回复
QunKangLi 2004-04-09
上面的代码打错了个字,更正:
class *pA = (A*)new pB ;//原来是class *pA = (A*)new pA ;
回复
QunKangLi 2004-04-09
如果要在普通函数中调用一个虚函数的本地版本(就是想要达到在构造和析构中调用的那种效果),用什么方法实现呢?

加上类前缀:
当B派生于A时,在A的函数中这样调用虚函数:
void A::fun()
{
A::vFun() ;//vFun是虚函数.
}
回复
QunKangLi 2004-04-09
看到这热闹,也来凑人气。

(1) 析构函数为什么一般不调用虚拟函数?
析构函数不能调用虚函数的原因,确实和虚表有关.
虚表是类的静态成员变量,在构造函数中基类与构造函数的初使化列表中的条目初使化完毕后,构造函数中用户代码前进行初使化为类自己实现的虚函数的指针.而析构函数同样在用户代码前重新将虚表中的项目设置为指向自己的函数实现.但不要忘了C++的构规则:创建对象时会首先调用基类的构造函数再凋用本类的构造函数;释放对象时则先调用自己的析构函数再调用基类的析构函数.但是当在析构函数中调用虚函数时会发生什么事呢?它会调用类自己的实现!(类自己没有实现的化用基类的实现),因为析构函数一开始就已经将虚表项进行了设置--等价于从它假设自己已经是类的派生链的最后一环了--而事实上确实如此,因为根据规则,它的派生类的的析构函数在此之前就已经调用了!注意,这里不可能有要调用的虚函数仅在派生类中实现了的情况,要是那样的话,链接时将会产生错误.
(2) 析构函数调用虚拟函数有什么作用?
析构函数中调用虚函数时,如前所说,将会把虚函数的实现限制在该类及其基本类中,即调用派生链中到该类为止的最后实现.
(3) 析构函数本身是虚函数的作用
确保正确地释放对象.特别是当用一个基类的指针向一个派生类对象时.考虑如下代码:
class B : public A {
public:
virtual ~B() ;
} ;
class *pA = (A*)new pA ;
delete pA ;

在最后delete pA时,它仅仅调用A的析构函数.如~B不是虚函数的话,将只析构A类的对象,属于B的资源将不被释放.但因为它是虚函数,而且因为在调用析构函数之前,虚表中的析构函数项暂时还没有被置为~A,目前是~B(),因而,它将保证调用B的析构函数以正确的释放资源,将虚表中析构函数项置为~A,那是~B调完成之后,自动层层调用B的基类的析构函数直至~A时才会发生的事.
回复
QunKangLi 2004-04-09
看到这热闹,也来凑人气。

(1) 析构函数为什么一般不调用虚拟函数?
析构函数不能调用虚函数的原因,确实和虚表有关.
虚表是类的静态成员变量,在构造函数中基类与构造函数的初使化列表中的条目初使化完毕后,构造函数中用户代码前进行初使化为类自己实现的虚函数的指针.而析构函数同样在用户代码前重新将虚表中的项目设置为指向自己的函数实现.但不要忘了C++的构规则:创建对象时会首先调用基类的构造函数再凋用本类的构造函数;释放对象时则先调用自己的析构函数再调用基类的析构函数.但是当在析构函数中调用虚函数时会发生什么事呢?它会调用类自己的实现!(类自己没有实现的化用基类的实现),因为析构函数一开始就已经将虚表项进行了设置--等价于从它假设自己已经是类的派生链的最后一环了--而事实上确实如此,因为根据规则,它的派生类的的析构函数在此之前就已经调用了!注意,这里不可能有要调用的虚函数仅在派生类中实现了的情况,要是那样的话,链接时将会产生错误.
(2) 析构函数调用虚拟函数有什么作用?
析构函数中调用虚函数时,如前所说,将会把虚函数的实现限制在该类及其基本类中,即调用派生链中到该类为止的最后实现.
(3) 析构函数本身是虚函数的作用
确保正确地释放对象.特别是当用一个基类的指针向一个派生类对象时.考虑如下代码:
class B : public A {
public:
virtual ~B() ;
} ;
class *pA = (A*)new pA ;
delete pA ;

在最后delete pA时,它仅仅调用A的析构函数.如~B不是虚函数的话,将只析构A类的对象,属于B的资源将不被释放.但因为它是虚函数,而且因为在调用析构函数之前,虚表中的析构函数项暂时还没有被置为~A,目前是~B(),因而,它将保证调用B的析构函数以正确的释放资源,将虚表中析构函数项置为~A,那是~B调完成之后,自动层层调用B的基类的析构函数直至~A时才会发生的事.
回复
yym314 2004-04-09
这是和对象的构造和析构顺序有关系的。
另外我感觉第一个问题和第二个问题有矛盾。
回复
nik_Amis 2004-04-09
...
回复
mzg3 2004-04-09
第一个问题我已经彻底的明白了
还有第二个问题啊:
析构函数调用虚拟函数有什么作用?
是不是有一些特殊的作用啊?

大家都来了
我再提一个问题:如果要在普通函数中调用一个虚函数的本地版本(就是想要达到在构造和析构中调用的那种效果),用什么方法实现呢?
回复
sevencat 2004-04-09
这段代码估计也能说明问题
//gcc
#include <iostream>

class A
{
public:
virtual ~A()
{
foo();
std::cout<<"~A"<<std::endl;
}
virtual void foo()
{
std::cout<<"foo in A"<<std::endl;
}
};

class B:public A
{
public:
virtual ~B()
{
foo();
std::cout<<"~B"<<std::endl;
}
virtual void foo()
{
std::cout<<"foo in B"<<std::endl;
}
};

class C:public B
{
public:
virtual ~C()
{
foo();
std::cout<<"~C"<<std::endl;
}
virtual void foo()
{
std::cout<<"foo in C"<<std::endl;
}
};

int main(int argc,char *argv[])
{
// C* xx=new C;
A* xx=new C;
delete xx;
return 0;
}
回复
rwdx 2004-04-09
试试下面的代码:
class A
{
public:
A(){};
virtual ~A(){PP();}
virtuan PP() = 0;
};

class B: public A
{
public:
B(){};
virtual ~B(){};
virtual PP(){};
};

int main(int argc, char** argv[], char** envp[])
{
A *a = new B();
B *b = new B();
delete a;
delete b;
}
回复
rwdx 2004-04-09
试试下面的代码:
class A
{
public:
A(){};
virtual ~A(){PP();}
virtuan PP() = 0;
};

class B public A
{
public:
B(){};
virtual ~B(){};
virtual PP(){};
};

int main(int argc, char** argv[], char** envp[])
{
A *a = new B();
B *b = new B();
delete a;
delete b;
}
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……