C++ 知识点基础问题

1、信号与槽机制 略作解释

信号与槽机制是观察者模式的一种实现,特性如下:

  1. 一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知;
  2. 一个槽就是一个观察者,通常就是在被观察的对象发生改变的时候——也可以说是信号发出的时候——被调用的函数;
  3. 信号与槽的连接,形成一种观察者与被观察都的关系;
  4. 当事件或者状态发生改变的时候,信号就会被发出;同时,信号发出者有义务调用所有注册的对这个事件(信号)感兴趣的函数(槽)。

信号槽与语言无关,有多种方法可以实现信号槽,不同的实现机制会导致信号槽的差别很大。信号槽术语最初来自Trolltech公司的QT库,由于其设计理念的先进性,立刻引起计算机科学界的注意,提出多种不同的实现。目前,信号槽依然是Qt库的核心之一,其它许多库也提供了类似的实现,甚至出现了一些专门提供这一机制的工具库。

信号槽是Qt对象以及其派生类对象之间的一种高效通信接口,是Qt的核心特性,也是Qt区别与其它工具包的重要地方。信号槽完全独立于标准的C/c++语言,因此要正确的处理好信号和槽,必须借助于一个成为MOC(Metal Object Compiler)的Qt的工具,MOC工具是一个C++预处理程序,能为高层次的事件处理自动生成所需要的的附加代码。

2、简单说下单例模式

在它的核心结构中保包含一个被称为单例的特殊类。通过单例模式可以保证应用该模式的系统只有一个实例。单例模式会阻止其他对象实例化其自己的对象的副本,从而确保所有对象都访问唯一实例。

3、Socket中listen()函数的作用

表示让一个套接字处于监听到来的连接请求的状态。listen函数使用主动连接套接字变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。

listen函数一般在调用bind之后且调用accept之前调用。

4、oop的基本特性

封装:把属于同一类事件的共性(包括属性与行为)归到一个类中。

继承:有些事物有共性,但还存在区别

多态:对这件抽象的事,对于每个个体(具体)又能找到其自身的行为去执行。

5、浅拷贝与深拷贝的区别,以及浅拷贝的危害

浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。

对两个指针进行释放,内存却被释放了两次,会造成内存错误问题!

6、父类的析构函数为什么为虚函数

如果基类没有定义为虚函数,则进行delete指向派生类的基类指针时,只会调用基类的析构函数,派生类的没有调用,如果在基类和派生类的构造函数中都有动态内存分配,那么就会存在内存泄漏。

7、什么情况下会调用拷贝构造函数

用类的一个对象去初始化另一个对象的时候

当函数的参数是对象(按值传递的时候)

当函数的返回值是对象或者引用的时候。

8、什么是多态,略作解释

接口的多种不同的实现方式即为多态,——同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向指针,来调用实现派生类中的方法。

实现多态的方法:虚函数,抽象类,覆盖,模板。

不同的对象对同一消息不同响应,子类可以重写父类的方法。

多态就是允许方法重名,参数或返回值可以是父类型传入或返回。

9、类成员函数的重载、覆盖和隐藏区别。

重载:是函数名相同,参数列表不同,重载只是在类的内部存在。但是不能靠返回类型来判断。相同的范围(在同一个类中),函数名字相同,参数不同,Virtual关键字可有可无。

覆盖:也叫重写,子类重新定义父类中相同名称和参数的虚函数,函数特征相同,但是具体实现不同,主要是在继承关系中出现的。

①范围,分别位于基类和派生类中。②函数的名称相同。③参数相同。④基类函数必须有Virtual关键字。

隐藏:也叫重定义,是指派生类的函数屏蔽了与其同名的基类函数,规则如下:

①如果派生类的函数和基类的函数同名,但是参数不同,此时,不管有无Virtual,基类的函数被隐藏。

②如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有Virtual关键字,此时,基类的函数被隐藏。

10、析构函数可以重载吗?

不能(重载的必要条件是参数的类型或者个数不一样或者顺序不一样,无参就不能重载);

11、this指针是什么?

this的目的总是指向这个对象,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。

12、什么是“引用“?声明和使用“引用”要注意哪些问题?

引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。

①&在此不是求地址运行,而是作标识作用。

②类型标识 是指目标变量的类型。

③声明引用时,必须同时对其进行初始化。

④引用声明完毕后,相当于目标变量有两个名称,不能再把该引用名作为其它变量的别名。

⑤声明一个引用,不是新定义也一个变量,它只表示该引用名是目标变量的一个别名,它本身不是一种数据类型,因此引用本身不占存储单元。

⑥不能建立数组的引用。

13、c++中new-delete与malloc-free的区别。

前者是C++的运算符,后者是C++/C标准库函数,对于非内部数据类型的而言,只用malloc-free无法满足动态对象的要求。库函数不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc-free。

1)申请的内存所在位置

new操作符从自由存储区(free stor)上为对象动态分配空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由储存区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。

那么自由存储区是否能够是堆(问题等价于new是否能够在堆上动态分配内存),这取决于operator new 的实现细节。自由存储区不仅可以是堆,还可以是静态存储区,这都看operator new 在哪里为对象分配内存。

2)返回类型安全性。

new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性操作符。而malloc内存分配 成功则下返回void *,,需要通过强制类型转换将void *指针转换成我们需要的类型。

3)内存分配失败时返回值。

new 内存分配失败时,会抛出bad_alloc异常,它不会返回NULL;malloc分配内存失败时返回NULL。

4)是否需要指定内存大小

使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自动计算,而malloc则需要显式地指出所需内存的尺寸。

5)是否调用对象的构造函数/析构函数

使用new操作符来分配对象内存时会经历三个步骤:①调用new函数分配一块足够大的,原始的,未命名的内存空间以便存储特定类型的对象。②编译器运行相应的构造函数以构造对象,并为其传入初值。③对象构造完成后,返回一个指向该对象的指针。

使用delete操作符来释放对象内存时会经历两个步骤:①调用对象的析构函数。②编译器调用delete函数释放内存。

而malloc则不会调用构造函数/析构函数。

14、空类占几个字节?为什么?

在c++中空类会占一个字节,这是上为了让对象的实例能够相互区别,具体来说,空类同样可以被实例化,并且每个实例在内存中都有独一无二的地址,因此,编译器会给空类隐含加上一个字节,这样空类实例化之后就会拥有独一无二的内存地址。如果没有这一个字节的占位,那么空类就无所谓实例化了,因为实例化的过程就是在内存中分配一块地址。

15、内联函数有什么特点?什么样的函数才称为内联函数?

特点:①消除调用函数和返回所造成的固有的开销。②函数会在它所调用的位置上展开。

定义时使用关键字 inline的函数叫做内联函数;

编译器在编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销;

内联函数体内不能有循环语句和switch语句;

内联函数的定义必须出现在内联函数第一次被调用之前;

对内联函数不能进行异常接口声明;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值