C++面试我一定会问的一个问题

C++是一门难学易用的语言,如果没有深刻理解一些基本概念,编写的代码就会经常出现一些奇怪的问题。

下面这个问题就是我当初学习C++ OOP概念时遇到的,也是我在工作中遇到的,这个问题没有复杂的技巧,也不是“茴香豆的茴有几种写法”之类的死板教条,只要你基础扎实,一定能回答出来。

问题很简单,我们都知道,C++中基类指针可以指向派生类对象,那么下面的代码是否正确?

#include <iostream>
using namespace std;

class Base
{
public:
   int a;

   Base(int a): a(a) {}
};

class Derived: public Base
{
public:
   Derived(int a): Base(a) {}

   void Print() {
       cout << "a: " << a << endl;
   }
};

int main()
{

  Derived d(100);
  Base* pb;
  pb = &d;
  pb->Print();

  return 0;
}

有啥想法了吗?

如果没有,编译时会输出下面信息,能看出什么端倪了吗?

$ g++ test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:27: error: ‘class Base’ has no member named ‘Print’

提示错误:基类‘Base’没有成员的名字是‘Print’,我们预想通过基类指针去调用派生类的函数成员。

“如果调用非虚函数,则无论实际对象是什么类型,都执行基类类型所定义的函数。”

–《C++ Primer》第四版中文版480页

没错,如果要想通过基类指针调用派生类的函数成员,得将函数定义成虚函数,像下面这样:

#include <iostream>
using namespace std;

class Base
{
public:
   int a;

   Base(int a): a(a) {}
   virtual ~Base() {}
   
   virtual void Print() {}
};

class Derived: public Base
{
public:
   Derived(int a): Base(a) {}

   virtual void Print() {
       cout << "a: " << a << endl;
   }
};

int main()
{

  Derived d(100);
  Base* pb;
  pb = &d;
  pb->Print();

  return 0;
}
$ g++ test.cpp -o test
$ ./test
a: 100

这里涉及到C++ OOP的多态概念,希望你通过此问题对C++多态有更深入的理解,如果有兴趣,还可以再研究下C++多态是怎么实现的,什么是虚函数表,相信你会有大彻大悟的感觉。

来源:星夜前往-博客

上一篇: C++11 | 从入门到放弃

下一篇: 后现代的系统编程语言——C++

分享到: 更多