如何判断一段程序是由C编译程序还是由C++编译程序编译的?
[标准答案]
#ifdef _ cplusplus
cout<<“c++”;
#else
cout<<“c”;
#endif
C++函数中值的传递方式有哪几种?
[标准答案] C++函数的三种传递方式为:值传递、指针传递和引用传递。
虚函数作用
提示该函数在齐一类中可能会被重写
应该被动态绑定,虚函数运行时由实际对象确定。
●C和C++有什么不同?
[参考答案]从机制上: c是面向过程的( 但c也可以编写面向对象的程序) ; c++是面向对象的, 提供了类。但是,c++编写面向对象的程序比c容易。
从适用的方向: c适合要求代码体积小的,效率高的场合,如嵌入式; c++适合更上层的,复杂的; linux核心大部分是c写的,因为它是系统软件,效率要求极高。
从名称上也可以看出,C++比c多了+,说明c++是c的超集;那为什么不叫c+而叫c++呢,是因为c++比
c来说扩充的东西太多了,所以就在c后面放上两个+;于是就成了c++。C语言是结构化编程语言,C++ 是面向对象编程语言。
C++侧重于对象而不是过程,侧重于类的设计而不是逻辑的设计。
C++中的struct和class有什么 区别?
[参考答案]从语法上讲,class和struct做 类型定义时只有两点区别:
(1)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理;
(2)成员的默认访问权限。class的成 员默认是private权限,struct默认 是public权限。
除了这两点,class和struct基本就是一个东西。语法上没有任何其它区别。
int id[sizeof(unsigned long)];这个对吗?为什么?
[标准答案] 正确这个sizeof是编译时运算符,编译时就确定了可以看成和机器有关的常量。
重载(overload)、 重写(override, 有的书也叫做“覆盖")重定义(redefinition) 的区别?
[标准答案]
重载
同一名字空间
是指允许存在多个同名函数,而这些函数的参数表不同。
重定义/隐
不同名字空间
用于继承,派生类与基类的函数同名,屏蔽基类的函数
重写/覆盖
不同名字空间
用于继承,子类重新定义父类虚函数的方法
如果在申请动态内存时找不到足够大的内存块,malloc和new将返回NULL指针,宣告内存申请失败。你是怎么处理内存耗尽的?
[参考答案]
(1)判断指针是否为NULL,如果是则马.上用return语句终止本函数。
(2)判断指针是否为NULL,如果是则马上用exit(1)终止整个程序的运行
(3)为new和malloc设置异常处理函数。例如VisualC++可以用set new_ _hander 函数为new设置用户自己定义的异常处理函数,也可以让malloc享用与new相同的异常处理函数。
C++是不 是类型安全的?
[参考答案]不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)。
main函数执行以前,还会执行什么代码?
[参考答案]全局对象的构造函数会在main函数之前执行。
C++中virtual与inline的含义分别是什么?
[参考答案]在基类成员函数的声明前加上virtual关键字,意味着将该成员函数声明为虚函数。inline与函数的定义体放在一起, 使该函数称为内联。inline是一 种用于实现的关键字,而不是用于声明的关键字。
虚函数的特点;如果希望派生类能够重新定义基类的方法,则在基类中将该方法定义为虚方法,这样可以启用动态联编。多态,纯虚函数,抽象类。
内联函数的特点;使用内联函数的目的是为了提高函数的运行效率。内联函数体的代码不能过长,因为内联函数省去调用函数的时间是以代码膨胀为代价的。内联函数不能包含循环语句,因为执行循环语句要比调用函数的开销大。
const关键字?有哪些作用
只读不改
[参考答案] const关 键字至少有下列n个作用:
(1)欲阻止-一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参, 表明它是一一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是-个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为‘左值”
VC中,编译工具条内的Debug与Release选项是什么含义?
[参考答案]Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。Debug带有大量的调试代码,运行时需要相应的运行库,发布模式程序紧凑不含有调试代码和信息,直接可以运行(如果不需要运行库)
是不是一个父类写了一个virtual函数,如果子类覆盖它的函数不加virtual,也能实现多态?
[参考答案] virtual修 饰符会被隐形继承的。virtual可 加可不加。子类的空间里有父类的所有变量(static除外)。同一个函数只存在一个实体(inline除外)。子类覆盖它的函数不加
virtual,也能实现多态。在子类的空间里,有父类的私有变量。私有变量不能直接访问。
函数中静态局部变量val的内存地址位于已初始化的数据段。
如何打印出当前源文件的文件名以及源文件的当前行号?
[标准答案]
cout <<FILE
cout<<LINE
FILE 和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。(c也有)
●当一个类A中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,请解释一下编译 器为什么没有让它为零
[标准答案]
为1。
分配空间的最小单位为1个字节。
如果是零的话,声明一个class A[10]对象数组,而每一个对象占用的空间是零,这时就没办法区分A[0],A[1]…了。
static使用:下一次函数调用需要受到上一次函数调用的影响才需要使用。
构造函数可否是虚函数,为什么?析构函数呢,可否是纯虚的呢?
构造函数不能为虚函数,要构造一-个对象,必须清楚地知道要构造什么,否则无法构造一个对象。
析构函数可以为纯虚函数。
在排序方法中,关键码比较次数与记录地初始排列无关的是()
A. Shell排序
B.归并排序
C.直接插入排序
p.选择排序
[标准答案]D
函数模板与类模板有什么区别?
[参考答案]函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。(需补充完善)
●函数重载,我们靠什么来区分调用的那个函数?靠返回值判断可以不可以?
[参考答案]如果同名函数的参数不同( 包括类型、顺序不同),那么容易区别出它们是不同的。如果同名函数仅仅是返回值类型不同,有时可以区分,有时却不能。例如:
void Function(void);
int Function (void);
上述两个函数,第一个没有返回值,第二个的返回值是int类型。如果这样调用函数:
int x = Function ();
则可以判断出Function是第二个函数。问题是在C++/C程序中,我们可以忽略函数的返回值。在这种情况下,编译器和程序员都不知道哪个Function函数被调用。
所以只能靠参数而不能靠返回值类型的不同来区分重载函数。
所有的运算符都能重载吗?
0 [参考答案]不能被重载的运算符在C++运算符集合中,有一些运算符 是不允许被重载的。这种限制是出于安全方面的考虑,可防止错误和混乱。(1)不能改变C++内部数据类型(如int,float等)的运算符。(2)不能重载‘’,因为‘.'在类中对任何成员都有意义,已经成为标准用法。(3)不能重载目前C++运算符集合中没有的符号,如#,@,$等。原因有两点,一是难以理解,二是难以确定优先级。(4)对已经存在的运算符进行重载时,不能改变优先级规则,否则将引起混乱。
基类的析构函数不是虚函数,会带来什么问题?
[参考答案]派生类的析构函数用不上,会造成资源的泄漏。
●介绍一下 模板和容器。如何实现?
(参考答案 ]
模板可以说比较古老了,但是当前的泛型编程实质上就是模板编程。它体现了一种通用和泛化的思想。
STL有7种主要容器:
vector, list,deque,map,multimap,set,multiset。
●拷贝构造函数相关问题,
深拷贝,浅拷贝,临时对
象等
深拷贝意味着拷贝了资源和指针,而浅拷贝只是拷贝了指针,没有拷贝资源。这样使得两个指针指向同- -份资源,造成对同一份析构两次,程序崩溃。
临时对象的开销比局部对象小些。。
以下代码能够编译通过吗,为什么?
unsigned int const size1= 2;
char str1[size1 ];
unsigned int temp= 0;
cin>> temp;
unsigned int const size2 = temp;char str2[ size2 ];
[标准答案] str2定义出错,size2非编译 器期间常量,而数组定义要求长度必须为编译期常量。
请你谈谈你在类中如何使用const的。
[参考答案]有时我们希望某些常量只在类中有效。
由于#define定义的宏常量是全局的,不能达到目的,于是想当然地觉得应该用const修饰数据成员来实现。const数据成员的确是存在的,但其含义却不是我们所期望的。const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。不能在类声明中初始化const数据成员。const数据成员的初始化只能在类构造函数的初始化表中进行。
两个互相独立的类:ClassA和ClassB,都各自定义了非静态的公有成员函数PublicFunc()和非静态的私有成员函数PrivateFunc();现在要在ClassA中增加定义一个成员函数ClassA::AdditionalPunction(ClassA a,ClassB b);则可以在AdditionalPunction(ClassAx,ClassB y)的实现部分(函数功能体内部)出现的合法的表达是最全的是:
A,x.PrivateFunc();x.PublicFunc();y.PrivateFunc();y.PublicFunc();B,x.PrivateFunc();x.PublicFunc();y.PublicFunc();
C,x.PrivateFunc();y.PrivateFunc();y.PublicFunc();
D,x.PublicFunc();y.PublicFunc();
[标准答案] B
写出判断ABCD四个表达式的是否正确,若正确,写出经过表达式中a的值。
inta=4;
(A)a += (a++); (B)a += (++a) ;
©(a++) += a; (D)(++a) += (a++);
a =?
[参考答案] C错误,左侧不是一个有效变量,不能赋值,可改为(++a) += a;改后答案依次为9,10,10,11
前缀++可以当左值,后缀++不可以当左值。
请你谈谈你是如何使用return语句的。
参考答案 return语句不可返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。(2)要搞清楚返回的究竟是“值”、“指针”还是“引用”。(3)如果函数返回值是一一个对象,要考虑return语句的效率。
构造函数可否是虚函数,为什么?析构函数呢,可否是纯虚的呢?
构造函数不能为虚函数,要构造一个对象,必须清楚地知道要构造什么,否则无法构造一个对象。
析构函数可以为纯虚函数。
●所有的运算符都能重载吗?
●[参考答案]不能被重载的运算符
在C++运算符集合中,有一-些运算符是不允许被重载的。这种限制是出于安全方面的考虑,可防止错误和混乱。
(1)不能改变C++内部数据类型(如int,float等)的运算符。
(2)不能重载‘’,因为‘.'在 类中对任何成员都有意义,已经成为标准用法。
(3)不能重载目前C++运算符集合中没有的符号,如#,@,$等。 原因有两点,一是难以理解,二是难以确定优先级。
(4)对已经存在的运算符进行重载时,不能改变优先级规则,否则将引起混乱。
●C++的空类,默认产生哪些类成员函数?
class Empty
public:
Empty(); //缺省构造函数
Empty (const Empty& ) ; //拷贝构造函数
~Empty(); //虚构函数
Empty& operator(const Empty& ) //赋值运算符
Empty& operator&(); //取址运算符
const Empty* operator&() const;//取址运算符const
拷贝构造函数相关问题,
深拷贝,浅拷贝,临时对象等
深拷贝意味着拷贝了资源和指针,而浅拷贝只是拷贝了指针,没有拷贝资源。这样使得两个指针指向同一份资源,造成对同一份析构两次,程序崩溃。
临时对象的开销比局部对象小些。。
在c++的一个类中声明一个static成员变量有没有用?
[参考答案]在C++类的成员变量被声明为static (称为静态成员变量),意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,也就是说不管创建多少对象,static修 饰的变量只占有一块内存。其修改值为该类的其它所有实例所见;而类的静态成员函数也只能访问静态成员(变量或函数)。static是加 了访问控制的全局变量,不被继承。
C++中为什么用模板类。
[参考答案]
(1)可用来创建动态增长和减小的数据结构
(2)它是类型无关的,因此具有很高的可复用性。
(3)它在编译时而不是运行时检查数据类型,保证了类型安全(4)它是平台无关的,可移植性
(5)可用于基本数据类型
●C++中哪些函数不能被声明为虚函数?
[标准答案]
普通函数(非成员函数),构造函数,内联成员函数、静态成员函数、友元函数。(1)虚函数用于基类和派生类,普通函数所以不能
(2)构造函数不能是因为虚函数采用的是虚调用的方法,允许在只知道部分信息的情况的工作机制,特别允许调用只知道接口而不知道对象的准确类型的方法,但是调用构造函数即使要创建一- 个对象,那势必要知道对象的准确类型。
(3)内联成员函数的实质是在调用的地方直接将代码扩展开
(4)继承时,静态成员函数是不能被继承的,它只属于一一个类,因为也不存在动态联编等
(5)友元函数不是类的成员函数,因此也不能被继承。
下面的代码有什么问题?class A {
public:
A(){ p=this;}
~A(){ if(p!=NULL){ delete p; p=NULL;} }A* p;
};
[标准答案] delete 会自动调用析构函数。所以析构中调用delete引起了无限递归