1、 下面的程序是否有错误,如果有错,请说明原因。
char* const pszHelp = “hello”;
pszHelp[0] = ‘a’;
因为 pszHelp 指向一个常量字符串,所以根本不允许修改字符串内容。除
非使用一个字符数组。
//armbbs注解:这个题目的答案错了,此处是正确的
2、 const 用法:
const char* p
p 是一字符串指针,该指针指向的内容是常量,指针指向的内容不
能被修改
char const* p
同上 char* const p
p 是一字符串指针,该指针是常量指针,指针不能被修改
3、 什么是抽象类
包含抽象函数的类是抽象类,满足 virtual fun() = 0; 的语法的函数是
抽象函数。主要用于提供接口,如同 Java 中的 Interface。
4、 什么时候需要使用虚拟析构函数
一般情况下类的析构函数都定义成虚函数,主要是考虑在使用基类指针操
作派生类对象时保证类的析构顺序。
5、 请指出下面代码存在的潜在问题
class CC {
int* m_pCount;
public:
void clear() { if ( m_pCount ) delete m_pCount; }
CC() { m_pCount = new int; }
~CC() { clear(); }
}
主要存在的问题是 clear 函数在 delete m_pCount;后并没有置指针为空
(m_pCount = NULL),这样当第二次调用 clear 时,会出现问题。
6、 如何定义禁止实例化的纯抽象基类
这个问题很奇怪,抽象类本身就不能被实例化,在程序编译时就会提示出错。
7、 在进行私有继承时,如何修改基类成员的存取权限
定义一个指向该基类的友元函数,就可以绕过私有继承操作基类成员。
8、 如何定义一个指向类的成员函数的指针
void (CC::*bfpClear)() = &CC::clear;
9、 类 A 派生类 B 和 C,类 D 从类 B、C 派生,如何将一个类 A 的指针指向
一个类 D 的指针
直接使用即可,主要是考察运行时多态的概念。本题和题 4 要一起考虑。
10、 请说出程序运行的结果 class A {
public:
virtual void func() { cout << “I am in base” << endl; };
}
class B : public A {
public:
virtual void func() { cout << “I am in derived” << endl; }
}
void main()
{
B* bb = new B;
bb->func();
A* aa = (A*)bb;
aa->func();
….
}
I am in derived
I am in derived
主要考察虚函数的使用
11、 分析下面代码,指出问题
int* func() { int i =0 ; return &i; }
返回的是一个局部简单类型变量地址,程序可能会出错,而且返回的指针
不能采用 delete 进行删除。
class CObject;
CObject* funobj() { CObject obj; …. return &obj; }
返回的是一个局部 CObject 类型变量地址,程序会出错,而且返回的指针
不能采用 delete 进行删除。
CString funobj() { CString strTemp = _T(“temp”); return strTemp; }
不会出错,返回的 CString 会调用 CString的拷贝构造函数返回。
12、 Debug 版本中经常使用 ASSERT 进行断言,在 Release 版本中有一个起
同样作用的函数,请说明。
VERIFY,而且要注意 ASSERT 中的语句在 Release 版本中会忽略。
13、 下面的程序是否有错误,如果有错,请说明原因。
struct A1 { int i; };
A1 a1;
a1.i = 0;
没有错误
class A1 { int i;};
A1 a1;
a1.i = 0;
有错误,未显示权限定义符缺省为 private。
14、 下面程序是否有错,有错,请说明原因。 :
char szTest[] = “hello”;
char* const psz = szTest;
psz[0] = ‘b’;
没有错误,psz 指向的字符串指针是常量,指针不能被修改,但指
针指向的内容可以修改
15、 在继承层次上,构造函数和析构函数的调用顺序如何?
构造函数:先基类,后派生类
析构函数:先派生类,后基类
16、 如果一个包容器中包含指向对象的指针,当从包容器中删除某个指针
时,会析构该指针指向的对象吗?
包容器并不关心存放对象的类型,所以从包容器中删除成员时,仅仅只是
从容器中释放该成员占有的空间。如果该成员是一个指向某个对象的指针,由
用户保证指针指向对象的内存释放。
17、 如何阻止构造函数的自动转换
首先要理解什么是构造函数的自动转换。
比如有
class A {….};
class B { B(A&) {…};};
func(B) {};
main()
{
A a;
Func(a);
}
在调用 Func(a)时,会自动调用 B(A&)构造函数,保证传给 Func 的参数是
B 类型。应该采用 explicit 关键字来防止构造函数的自动转换。
18、 类的成员函数作为回调函数有什么要求?
必须是静态成员函数。
19、 分析代码,给出 i, j ,k 的结果。
int i = 0, j = 0; k = 0;
if (++i || j++ || ++k ) {}
主要是注意前置操作符和后置操作符的区别,还要考虑 或操作 在条件判
断中的实现(如果一个为真,则不进行后续判断) 。
i = 1, j = 0, k = 0