C++ 笔试题 虚函数, 难

languagec 2009-11-24 03:40:25
#include <iostream>
#include <string>
using namespace std;

void println(const std::string& msg)
{
std:cout<<msg<<'\n';
}

class Base{
public:
Base() {
println("Base::Base()");
Virt();
}
void f(){
println("Base::f()");
Virt();
}
virtual void Virt(){
println("Base()::virt()");
}
};

class Derived:public Base
{
public:
Derived(){
println("Derived:: Derived ()");
Virt();
}

virtual void Virt(){
println("Derived ()::virt()");
}
};

int main(int argc,char* argv[])
{
Derived d;
Base *pB=&d;
pB->f();
}


输出结果是
Base::Base()
Base()::virt()
Derived:: Derived ()
Derived ()::virt()

Base::f()
Derived ()::virt()


为什么?
...全文
624 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyc23 2009-11-26
  • 打赏
  • 举报
回复
顶上
bvbook 2009-11-25
  • 打赏
  • 举报
回复



求职面试,可以看《编程之美——微软技术面试心得》
yyc23 2009-11-25
  • 打赏
  • 举报
回复
这个题目考察两点:
第一:在构造函数中调用虚函数,那么虚拟机制就不会发生作用,也就是不能实现多态性。
究其原因是基类的构造函数执行时,派生类的数据成员还未初始化,虚函数不能向下匹配到派生类,因此执行的还是基类的虚函数。
第二:基类的指针指向派生类的对象,基类指针调用其成员函数体中有调用虚函数,那么也能实现多态,只不过不是直接调用虚函数罢了。
lxfhfut 2009-11-25
  • 打赏
  • 举报
回复
其实只要知道 在构造函数中调用的虚函数不具有多态性,而在普通成员函数或其他函数中直接调用虚函数是具有多态性的。。。
xinjiXJZ 2009-11-25
  • 打赏
  • 举报
回复
~~~~
jhony_lee 2009-11-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 akirya 的回复:]
不要在构造函数中调用虚函数
[/Quote]
顶一下
zhangjie199011087 2009-11-24
  • 打赏
  • 举报
回复
没有意思啊!
机智的呆呆 2009-11-24
  • 打赏
  • 举报
回复
像上面构造函数中的虚函数是静态绑定的。
macrojj 2009-11-24
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 qiuyatao 的回复:]
引用楼主 languagec 的回复:
#include <iostream>
#include <string>
using namespace std;

void println(const std::string& msg)
{
    std:cout < <msg < <'\n';
}

class Base{
    public:
    Base() {
        println("Base::Base()");
        Virt();
    }
    void f(){
        println("Base::f()");
        Virt();
    }
    virtual void Virt(){
        println("Base()::virt()");
    }
};

class Derived:public Base
{
public:
    Derived(){
        println("Derived:: Derived ()");
        Virt();
    }

    virtual void Virt(){
        println("Derived ()::virt()");
    }
};

int main(int argc,char* argv[])
{
    Derived d;
    Base *pB=&d;
    pB->f();
}


输出结果是
Base::Base()
Base()::virt()
Derived:: Derived ()
Derived ()::virt()

Base::f()
Derived ()::virt()


为什么?



看到这个题我突然想请教高手另一个问题,在主函数Derived d;的时候,在d调用构造函数的时候Derived的对象还没生成,也就是d还没完全生成。此时调用Virt();的话this指针不是应该指向基类吗?请高手指点!谢谢
[/Quote]

是啊。。。所以结果的前两个是:
Base::Base()
Base()::virt()
wangxipu 2009-11-24
  • 打赏
  • 举报
回复

一点不实用的题目
构造函数里面调用虚函数
lovesi3344 2009-11-24
  • 打赏
  • 举报
回复
好问题
J10FX 2009-11-24
  • 打赏
  • 举报
回复
子类创建一个对象的时候会首先调用基类的构造函数然后在调用本类的构造函数,这样以来对象才算建立,你要想实现多态的话,那么基类的虚函数和子类的虚函数一定要一致
qiuyatao 2009-11-24
  • 打赏
  • 举报
回复
[Quote=引用楼主 languagec 的回复:]
#include <iostream>
#include <string>
using namespace std;

void println(const std::string& msg)
{
    std:cout < <msg < <'\n';
}

class Base{
    public:
    Base() {
        println("Base::Base()");
        Virt();
    }
    void f(){
        println("Base::f()");
        Virt();
    }
    virtual void Virt(){
        println("Base()::virt()");
    }
};

class Derived:public Base
{
public:
    Derived(){
        println("Derived:: Derived ()");
        Virt();
    }

    virtual void Virt(){
        println("Derived ()::virt()");
    }
};

int main(int argc,char* argv[])
{
    Derived d;
    Base *pB=&d;
    pB->f();
}


输出结果是
Base::Base()
Base()::virt()
Derived:: Derived ()
Derived ()::virt()

Base::f()
Derived ()::virt()


为什么?

[/Quote]

看到这个题我突然想请教高手另一个问题,在主函数Derived d;的时候,在d调用构造函数的时候Derived的对象还没生成,也就是d还没完全生成。此时调用Virt();的话this指针不是应该指向基类吗?请高手指点!谢谢
macrojj 2009-11-24
  • 打赏
  • 举报
回复
主要是 f()不是虚函数 然后 virt()是虚函数。
你可以这样想。virt 是this 指针调用的。 所以在虚函数寻址的时候,查的是派生类的虚函数表,所以找到了派生类的virt 。
rabbitlzx 2009-11-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 benbshmily 的回复:]
Base::Base()
Base()::virt()
Derived:: Derived ()
Derived ()::virt()

以上是Derived d; 定义对象d是调用构造函数时打印的结果,这个只要知道构造函数调用顺序就ok。
Base *pB=&d;
    pB->f();
这样基类的指针指向派生类对象后,调用f函数时传入的this指针是指向d的,因此在f函数里调用virt() 函数时就调用到了派生类的版本,常见的多态瑟。所以打印出下面结果。

Base::f()
Derived ()::virt()

个人感觉不难.......
[/Quote]

up
zhangyinze123 2009-11-24
  • 打赏
  • 举报
回复
基类中的虚函数,由派生类实现!
函数的多态性
benbshmily 2009-11-24
  • 打赏
  • 举报
回复
Base::Base()
Base()::virt()
Derived:: Derived ()
Derived ()::virt()

以上是Derived d; 定义对象d是调用构造函数时打印的结果,这个只要知道构造函数调用顺序就ok。
Base *pB=&d;
pB->f();
这样基类的指针指向派生类对象后,调用f函数时传入的this指针是指向d的,因此在f函数里调用virt() 函数时就调用到了派生类的版本,常见的多态瑟。所以打印出下面结果。

Base::f()
Derived ()::virt()

个人感觉不难.......
  • 打赏
  • 举报
回复

int main(int argc,char* argv[])
{
Derived d;
Base *pB=&d;
pB->f();
}

Base::Base()
Base()::virt()
Derived:: Derived ()
Derived ()::virt()
/*上述结果出现的原因:由于创建一个派生类对象,所以先调用基类构造函数,那么输出是
Base::Base()
Base()::virt() ,然后调用派生类构造函数,输出结果为Derived:: Derived ()
Derived ()::virt() */
Base::f()
Derived ()::virt()
/*由于f()为基类特有,所以输出有Base::f() ,而virt()为虚函数,此时调用派生类中的virt()*/

pady_pady 2009-11-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 akirya 的回复:]
不要在构造函数中调用虚函数
[/Quote]
顶下,
LeonTown 2009-11-24
  • 打赏
  • 举报
回复
f()函数是普通的继承,
而Virt()函数才是多态
加载更多回复(3)

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧