20161017
1.当一个类A 中没有声明任何成员变量与成员函数,这时sizeof(A)的值是多少?
1
0
4
运行时错误
百度:class CBase
{
};
运行cout<<"sizeof(CBase)="<<sizeof(CBase)<<endl;
sizeof(CBase)=1;
深度探索c++对象模型中是这样说的: 那是被编译器插进去的一个char ,使得这个class的不同实体(object)在内存中配置独一无二的地址。 也就是说这个char是用来标识类的不同对象的。
2指出下面程序哪里可能有问题?
class CBuffer
{
char * m_pBuffer;
int m_size;
public:
CBuffer()
{
m_pBuffer=NULL;
}
~CBuffer()
{
Free();
}
void Allocte(int size) (1) {
m_size=size;
m_pBuffer= new char[size];
}
private:
void Free()
{
if(m_pBuffer!=NULL) (2)
{
delete[] m_pBuffer;
m_pBuffer=NULL;
}
}
public:
void SaveString(const char* pText) const (3)
{
strcpy(m_pBuffer, pText); (4)
}
char* GetBuffer() const
{
return m_pBuffer;
}
};
void main (int argc, char* argv[])
{
CBuffer buffer1;
buffer1.SaveString("Microsoft");
printf(buffer1.GetBuffer());
}
|
1
2
3
4
正确答案应该为: A C D
理由: (1) 分配内存时, 未检测m_pBuffer是否为空, 容易造成内存泄露;
(3) 常成员函数不应该对数据成员做出修改, 虽然可以修改指针数据成员指向的数据, 但原则上不应该这么做;
(4) 字符串拷贝时, 未检测是否有足够空间, 可能造成程序崩溃。
以下程序的运行结果是:
1
2
3
4
5
|
int
main(
void
){
int
m=5;
if
(m++>5)cout<<m<<endl;
else
cout<<--m;
}
|
正确答案: B 你的答案: A (错误)
4
5
7
6
类B从类A派生,则类B可以访问类A中的( )成员?
正确答案: A C 你的答案: C D E (错误)
public成员
private成员
protected成员
数据成员
函数成员
x为整型,请用位运算实现x%8
1 。
你的答案 (错误)
1 x&8
参考答案 x&7
x为整型,请用位运算实现x%8
1 。
你的答案 (错误)
1 x&8
参考答案 x&7
请阅读下面代码片段并且回答问题:
关于这段代码,下列说法正确的是
1
2
3
4
5
6
7
8
9
10
11
12
|
#define SIZE_20M (20*1024*1024)
void
func_a()
{
char
*temp =
malloc
(SIZE_20M)
return
;
}
void
func_b()
{
char
temp[SIZE_20M];
//...do something using temp
return
;
}
|
关于这段代码,下列说法正确的是
正确答案: B 你的答案: D (错误)
func_a 获得临时内存的方式效率通常更高。
func_b 使用了太多的栈,程序可能会在运行时候崩溃。
func_b 存在内存泄露
func_a 和func_b 分配的内存会自动初始化0
//A.栈区效率比堆区高,malloc分配的空间在堆区,临时变量分配在栈区。
区别是:栈区由电脑自己清除(用完自动删),堆区需要程序员清除,或者程序结束后由系统清除
B.栈一般能放2M大小
C.func_a会发生内存泄漏(使用动态内存分配,使用完未删除就会造成泄漏。或者是如果没有任何一个指针指向那块动态内存,那它就泄漏了)
D.堆区和栈区都不会自动初始化,自动初始化会在未赋值的静态/全局区。
void * malloc(usingned int size);单位是(byte)字节数
其作用是在内容的动态存储区分配一个长度位 side 空间,此函数是一个指针型函数,返回的指针是该分配区域的开头的位置(或首地址)
注意指针的类型位void 即不指向任何类型的数据,只提供一个地址。放什么类型的数据,强制转换为什么类型。
如果函数未能成功申请到空间(内存不足),返回空指针 NULL】
上面的代码也该改为
1
|
char
*temp = (
char
*)
malloc
(SIZE_20M);
|
x为整型,请用位运算实现x%8
1 。
你的答案 (错误)
1 x&8
参考答案 x&7
声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*,正确的是()
正确答案: C 你的答案: C (正确)
(int *p[10])(int*)
int [10]*p(int *)
int (*(*p)[10])(int *)
int ((int *)[10])*p
以上选项都不正确
首先题目说要声明一个数组指针, 一般我们想到的数组指针是 随便来一个 int(*p)[10], 然后又说每个元素是一个函数指针,那么我们随便来一个 函数指针 int (*pf)(int *) . 然后把(*p)[10]作为一个整体替代 pf 即 int(*(*p)[10]))(int *); 分析: 判断一个复杂式子看最高优先级的,*p是一个指针,然后(*p)外面是[],所以是数组指针,
(*p)[10])描述完毕,然后再看外面int(*)(int *)很明显,这是一个函数指针,所以这个数组中每个元素是函数指针
如下程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#include "stdio.h"
class
Base
{
public
:
Base()
{
Init();
}
virtual
void
Init()
{
printf
(
"Base Init\n"
);
}
void
func()
{
printf
(
"Base func\n"
);
}
};
class
Derived:
public
Base
{
public
:
virtual
void
Init()
{
printf
(
"Derived Init\n"
);
}
void
func()
{
printf
(
"Derived func\n"
);
}
};
int
main()
{
Derived d;
((Base *)&d)->func();
return
0;
}
|
该程序的执行结果
-
Base Init Derived func
-
Base Init Base func
-
Derived Init Base func
-
Derived Init Derived func
8个回答
添加回答-
在构造函数不要调用虚函数。在基类构造的时候,虚函数是非虚,不会走到派生类中,既是采用的静态绑定。显然的是:当我们构造一个子类的对象时,先调用基类的构造函数,构造子类中基类部分,子类还没有构造,还没有初始化,如果在基类的构造中调用虚函数,如果可以的话就是调用一个还没有被初始化的对象,那是很危险的,所以C++中是不可以在构造父类对象部分的时候调用子类的虚函数实现。但是不是说你不可以那么写程序,你这么写,编译器也不会报错。只是你如果这么写的话编译器不会给你调用子类的实现,而是还是调用基类的实现。
在析构函数中也不要调用虚函数。在析构的时候会首先调用子类的析构函数,析构掉对象中的子类部分,然后在调用基类的析构函数析构基类部分,如果在基类的析构函数里面调用虚函数,会导致其调用已经析构了的子类对象里面的函数,这是非常危险的。
发表于 2015-07-18 21:45:30 回复(1) -
Derived d;首先创建对象d,找到基类的构造函数Base(){Init();},此时需要调用Init()函数,不要被virtual迷惑,这只是普通的调用函数,虚函数不起作用,所以调用的还是基类的Init(),输出Base Init;((Base *)&d)->func(),虽然是动态联编,但是func()不是虚函数,Base*指针指向派生类不起作用,执行的是基类的func(),输出Base func;
故选 B编辑于 2015-10-05 21:59:05 回复(3) -
1. 子类Derived中并没有定义构造函数,因此在执行Derived d语句的时候会掉用基类中的构造函数,因此输出 Base Init2.基类中的void func()函数并没有定义成 virtual void func() = 0;的形式,因此,((Base *)&d)即基类对象的指针所调用的func为基类中的func
-
-