【面试】 CVTE 视源股份 C++ 软件开发 一面

本文分享了CVTE视源股份C++软件开发一面的面试题,涵盖C++的三大特性、虚函数原理、多继承下的虚表指针、类模板与函数模板的区别、STL特性、vector扩容及缩容设计、C++11新特性、TCP滑动窗口和TCP与UDP的区别等知识点。
摘要由CSDN通过智能技术生成

微信搜索“编程笔记本”,获取更多信息
------------- codingbook2020 -------------

面经面经面经!今天分享的是 CVTE 视源股份C++ 软件开发一面面试题,CVTE 的面试题是真的多!面对疾风吧!!!

面试题

1.1 C++ 的三大特性是什么?什么是多态?

C++ 的三大特性是封装性继承性多态性

  • 封装性
    C++语言中支持数据封装,是支持数据封装的工具,对象是数据封装的实现。所谓封装具有两方面的含义:一是将有关的数据和操作代码封装在一个对象中,各个对象相互独立,互不干扰。二是将对象中某些数据与操作代码对外隐蔽,即隐蔽其内部细节,只留下少量接口,以便与外界联系,接收外界消息。
  • 继承性
    一个类(基类)可以根据需要生成它的派生类,派生类还可以再生成派生类。继承机制允许派生类继承基类的数据和操作,也就是说允许派生类使用基类的数据和操作,同时派生类还可以增加新的数据和操作。
  • 多态性
    面向对象中的多态性指的是不同的对象收到相同的消息时产生多种不同的行为。实现多态的方法主要两种,一种是编译时多态,主要由重载模板来实现;一种是运行时多态,主要由虚函数(包括继承)来实现。

1.2 虚函数的工作原理?

C++ 中的虚函数的作用主要是实现了多态的机制。基类定义虚函数,子类可以重写该函数。
当子类重新定义了父类的虚函数后,当父类的指针指向子类对象的地址时,父类指针根据赋给它的不同子类指针,动态地调用子类的该函数,而不是父类的函数,且这样的函数调用发生在运行阶段,而不是发生在编译阶段,称为动态联编

更通俗地说就是:如果使用了 virtual 关键字,程序将根据引用或指针指向的对象类型来选择方法,否则使用引用类型或指针类型来选择方法。

请看一个例子:

#include <iostream>

using namespace std;

class Father {
public:
    virtual void show() {
        cout << "This is class Father" << endl;
    }
};

class Son : public Father {
public:
    void show() {
        cout << "This is class Son" << endl;
    }
};

int main()
{
    Father *f = new Son;
    f->show();

    return 0;
}

/*
编译运行:
jincheng@jincheng-PC:~/Desktop$ g++ -o test test.cpp
jincheng@jincheng-PC:~/Desktop$ ./test
This is class Son
*/

可以看到,父类指针根据赋给其的具体子类指针,调用子类的方法,而非父类的方法。若父类中的该方法未声明为 virtual ,则父类指针只会调用父类方法。请看下面的例子:

#include <iostream>

using namespace std;

class Father {
public:
    // virtual void show() {
    void show() {
        cout << "This is class Father" << endl;
    }
};

class Son : public Father {
public:
    void show() {
        cout << "This is class Son" << endl;
    }
};

int main()
{
    Father *f = new Son;
    f->show();

    return 0;
}

/*
编译运行:
jincheng@jincheng-PC:~/Desktop$ g++ -o test test.cpp
jincheng@jincheng-PC:~/Desktop$ ./test
This is class Father
*/

介绍完虚函数的功能后,我们再来看一下虚函数是如何工作的。

编译器处理虚函数的方法是:为每个类对象添加一个隐藏成员,隐藏成员中保存了一个指向数组的指针,数组的元素是函数地址,这种数组成为虚函数表,这样的指针称为虚表指针。即,每个类使用一个虚函数表,每个类对象使用一个虚表指针。

举个例子:基类对象包含一个虚表指针,指向基类中所有虚函数的地址表。派生类对象也将包含一个虚表指针,指向派生类虚函数表。看下面两种情况:

  • 如果派生类重写了基类的虚方法,该派生类虚函数表将保存重写的虚函数的地址,而不是基类的虚函数地址。
  • 如果基类中的虚方法没有在派生类中重写,那么派生类将继承基类中的虚方法,而且派生类中虚函数表将保存基类中未被重写的虚函数的地址。
  • 如果派生类中定义了新的虚方法,则该虚函数的地址也将被添加到派生类虚函数表中。

通过上面的分析我们知道了虚函数的引入是为了实现运行时多态,也了解到虚函数的调用比普通函数的开销要大(查表)。

有关虚函数在析构函数中的使用,参见往期笔记:面试 C++ 工程师:为什么析构函数必须是虚函数?为什么默认的析构函数不是虚函数?

1.3 如果是多重继承只有一个虚表指针吗

在多继承情况下,有多少个含有虚函数的基类就有多少个虚函数表和虚表指针

1.4 使用过类模板吗?函数模板和类模板的区别是什么?

类模板

所谓类模板,实际上是建立一个通用类,其数据成员、成员函数的返回值类型和形参类型不具体指定,用一个虚拟的类型来代表。使用类模板定义对象时,系统会根据实参的类型来取代类模板中虚拟类型从而实现了不同类的功能。

其框架如下:

template<class T, class V>
class Class_Name {
public:
    T func_name(T a, V b) {
        //
    }

private:
    T val;
    V *p;
}

或者

template<typename T, typename V>
class Class_Name {
public:
    T func_name(T a, V b) {
        //
    }

private:
    T val;
    V *p;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值