C++基础问答:
1、什么是类的成员函数?
类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。成员函数可以定义在类定义内部,或者写在类定义外部可以单独使用范围解析运算符 :: 来定义。
2、const是什么?怎么用?
在 C++ 中,有两种简单的定义常量的方式:
- 使用 #define 预处理器。
- 使用 const 关键字。
const关键字是用来定义常量的,比如 const int LONG 5;在代码中出现LONG其值就为5.
3、类和对象的区别?
定义一个类,本质上是定义一个数据类型的蓝图。这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。也可以指定类的成员为 private 或 protected。类提供了对象的蓝图,所以基本上,对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。
类是抽象的,对象是具体的。比如说一个类叫做people,它有数据成员name,age,sex。创建两个people的对象p1,p2。这两个对象则拥有不同的数据成员,p1.name = Jone,p1.age = 20,p1.sex = man;p2.name = Mary,p2.age = 21,p1.sex =women。
4、结构化程序设计的三种基本控制结构是什么?
- 顺序结构:按照先后顺序依次执行程序中的语句
- 选择结构:按照给定条件有选择地执行程序中的语句if else\switch case
- 循环语句:按照给定规则重复地执行程序中的语句while\for\do while
5、什么是析构函数?
析构函数的作用是:对象在销毁之前,做一个清理善后的工作;当类的实例超出作用域时,析构函数被自动调用。析构函数跟构造函数一样,如果你没有编写自己的析构函数,编译器会自动提供一个默认析构函数。 派生类调用的析构函数顺序是“先子类,后基类”.
析构函数的规则:
1. 析构函数的名称与其所属类的名称相同,只是名称前使用了符号”~“
2. 析构函数没有返回类型
3. 与构造函数不同,析构函数没有输入参数,因此不能重载,一个类只有一个析构函数
6、友元函数是什么?
在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。
性质:
1)友元函数不被继承
2)友元关系是单向的,不具有交换性。比如A是B的友元,则类B的成员函数可以访问类A的对象的任何成员,反之不可
3)友元关系不具有传递性。比如A是B的友元,B是C的友元,不能推出A是C的友元。
7、C++中编译器所生成的目标文件扩展名是什么?
C++程序编译后生成的文件:
.exe :可执行文件,点击即可运行
.ilk :当选定渐增型编译链接时,连接器自动生成ILK文件,记录链接信息
.obj :目标文件,obj文件与cpp文件名字一一对应
.pch :prcompiled-header,预编译头文件
.idb :文件保存的信息,使编译器在重新编译的时候只重新编译改动过的函数和最新类定义改动过的源文件,这样可提高变异速度
.pdb :Program Database,即程序数据库文件,用来记录调试信息
.dsp :Developer Studio Project,配置文件
.ncb :No Compile Browser,其中存放了供ClassView、WizardBar和Component Gallery使用的信息,由VC开发环境自动生成
.plg :超文本文件,可以用IE打开,记录build的过程
.cpp :C++源文件
8、通常拷贝构造函数是什么?深拷贝和浅拷贝有何不同?
首先对于普通类型的对象来说,它们之间的复制是很简单的,例如:
int a =100; int b =a ;
而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。例如:
int main()
{
CExample A(100);//CExample是一个类,A是对象,传参100
CExample B = A; //注意这里的对象初始化要调用拷贝构造函数,而非赋值
B.Show ();
return 0;
}
public:
//构造函数
CExample(int b)
{ a = b;}
//拷贝构造函数
CExample(const CExample& C)
{
a = C.a;
}
可见,拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量。
所谓浅拷贝,指的是在对象复制时,只对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝。大多情况下“浅拷贝”已经能很好地工作了,但是一旦对象存在了动态成员,那么浅拷贝就会出问题了。有动态成员的情况下,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次,这就是错误出现的原因。
在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间。
9、运算符号的重载是什么?
改变运算符的运算过程叫运算符重载。如果C++预定义的基本数据类型的运算符重载将不再适合我们使用,我们要改变编译程序帮我们完成的预定义中间的运算过程 把自己定义的数据类型(如自己定义的类)的变量进行算,这时我们需要自行重载运算符。
运算符重载分为普通运算符重载(“ + ”、“ - ”、“ * ”、“ / ”等)、前置运算符重载("++"、"--")、后置运算符重载("++"、"--")、插入运算符重载(">>")、提取运算符重载("<<")。
运算符重载的方式有两种:
(1)令运算符重载函数作为类的成员函数
(2)令运算符重载函数作为类的友元函数
10、类中构造函数的作用?
构造函数用于解决类中的对象初始化的问题 ,构造函数是一类特殊的函数,与其他的成员函数不同的是构造函数不需要用户来调用它,而是建立对象的时候自动的执行。构造函数不需要用户调用,也不能够被用户调用。带参数的构造函数中的形参,其对应的实参在定义对象时给定。 使用带有参数的构造函数可以方便的实现对不同的对象进行初始化。
11、动态联编需要满足什么条件?
虚函数必须采用指针或引用。
联编:将一个调用函数者连接上正确的被调用函数,这一过程叫做函数联编,一般简称为联编。
动态联编(加virtual):预先不知道调用那个对象的函数,运行时动态的选择调用那个对象的函数。father *p=new son;//如果father函数是虚函数,p调用实际的对象,而如果father函数不是虚函数,p调用的是father的函数和变量。(如果在虚函数没有采用指针或者引用,那么就无法实现动态联编)
静态联编(不加virtual):运行之前就确定好了那个指针指向那个对象,而且在运行时不能改变/编译时就解决了程序中的操作调用与执行该操作代码间的关系。(所以代码在编译和运行时是一样的)
区别:静态联编由于对象不用对自身进行跟踪,因此速度浪费比较小。而动态联编虽然可以动态追踪对象,灵活性比较强。但是速度浪费也比较严重。
12、什么是内联函数?
在C++中,函数调用需要建立栈环境,进行参数复制,保护调用现场,返回时,还要进行返回值复制,恢复调用现场。这些工作都是与完成特定任务的操作无关的额外开销。程序效率由于该项工作而受到影响。可以将函数声明为内联函数,内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)。对函数的内联声明必须在调用之前。因为内联函数的代码在程序运行时是直接嵌在调用执行处,它不影响链接,只在编译时确定运行代码。因此编译时,在调用之前看到内联函数声明就十分重要。
内联函数体应该尽可能小,且结构要简单,不能含有复杂的控制语句如switch和while。内联函数相对于普通函数的优势只是省去了函数调用时压栈,跳转和返回的开销。 因此,当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么内联将无意义。
内联函数使用的场合一般为:
(1)函数体适当小,这样就使嵌入工作容易进行,不会破坏原调用主体。
(2)程序中特别是在循环中反复执行该函数,这样就使嵌入的效率相对较高。
(3)程序并不多处出现该函数调用,这样就使嵌入工作量相对较少,代码量也不会剧增。
13、多态的实现原理是什么?什么是虚函数?
多态:C++中通过虚函数实现动多态。虚函数的本质就是通过基类访问派生类定义的函数。每一个含有虚函数的类,其实例对象内部都有一个虚函数表指针,该虚函数表指针被初始化为本类的虚函数表的内存地址。所以在程序中,不管对象类型如何转换,但该对象内部的虚函数表指针是固定的,这样才能实现动态地对对象函数进行调用,这就是C++多态性的原理。
虚函数:指向基类的指针在操作它的多态类对象时,会根据不同的类对象调用其相应的函数,这个函数就是虚函数,虚函数用virtual修饰函数名。虚函数的作用是在程序的运行阶段动态地选择合适的成员函数。在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型,(参数类型的顺序也要一致),以实现统一的接口。如果在派生类中没有重新定义虚函数,则它继承基类的虚函数。
14、模板函数和函数模板、类函数和模板类的区别?
在 C++ 中,模板分为函数模板和类模板两种。函数模板是用于生成函数的,类模板则是用于生成类的。
函数模板&模板函数 类模板&模板类 必须区分概念
函数模板是模板,模板函数时具体的函数
类模板是模板,模板类时具体的类
由函数模板实例化而得到的函数称为模板函数
由类模板实例化得到的类叫模板类
15、iostream.h、stdio.h、fstream.h,stdlib.h这几个头文件的作用是什么?
c/c++的常用头文件
//标准C的头文件
#include <ctype.h>//字符处理
#include <errno.h>//定义错误码
#include <float.h>//浮点数处理
#include <fstream.h>//文件输入/输出
#include <iomanip.h>//参数化输入/输出
#include <iostream.h> //数据流输入/输出
#include <limits.h> //定义各种数据类型最值常量
#include <locale.h> //定义本地化函数
#include <math.h> //定义数学函数
#include <stdio.h> //定义输入/输出函数
#include <stdlib.h> //定义杂项函数及内存分配函数
#include <string.h> //字符串处理
#include <strstrea.h> //基于数组的输入/输出
#include <time.h> //定义关于时间的函数
#include <wchar.h> //宽字符处理及输入/输出
#include <wctype.h> //宽字符分类
16、this指针存在的目的是什么?
在面向对象程序设计中,每个非静态成员函数中都包含一个特殊的指针,指向调用该函数的对象,这个指针称为this指针。this是指向实例化对象本身时候的一个指针,里面存储的是对象本身的地址,通过该地址可以访问内部的成员函数和成员变量。
什么需要this?因为this作用域是在类的内部,自己声明一个类的时候,还不知道实例化对象的名字,所以用this来使用对象变量的自身。在非静态成员函数中,编译器在编译的时候加上this作为隐含形参,通过this来访问各个成员(即使你没有写上this指针)。
关于this指针的一个经典回答:当你进入一个房子后,你可以看见桌子、椅子、地板等,但是房子你是看不到全貌了。对于一个类的实例来说,你可以看到它的成员函数、成员变量,但是实例本身呢?this是一个指针,它时时刻刻指向你这个实例本身
17、什么是宏定义?有什么作用?
宏定义是替换,不做计算,也不做表达式求解。简称宏。
格式:#define 标识符 字符串
(1)宏名一般用大写
(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义
(3)提高程序的可维护性