资源描述
精选资料
17.面向对象的三个基本特征,并简单叙述之?
1. 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private, protected,public)
2. 继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。
3. 多态:是将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
18. 重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?
常考的题目。从定义上来说:
重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
重写:是指子类重新定义复类虚函数的方法。
从实现原理上来说:
重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的。也就是说,它们的地址在编译期就绑定了(早绑定),因此,重载和多态无关!
重写:和多态真正相关。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚绑定)。
19. 多态的作用?
主要是两个:1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。
27.struct 和 class 的区别
答案:struct 的成员默认是公有的,而类的成员默认是私有的。struct 和 class 在其他方面是功能相当的。
从感情上讲,大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位,而类就象活的并且可靠的社会成员,它有智能服务,有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为,那么只有在你的类有很少的方法并且有公有数据(这种事情在良好设计的系统中是存在的!)时,你也许应该使用 struct 关键字,否则,你应该使用 class 关键字。
32.请说出const与#define 相比,有何优点?
答案:1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。
33.简述数组与指针的区别?
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。
(1)修改内容上的差别
char a[] = “hello”;
a[0] = ‘X’;
char *p = “world”; // 注意p 指向常量字符串
p[0] = ‘X’; // 编译器不能发现该错误,运行时错误
(2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。C++/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
char a[] = "hello world";
char *p = a;
cout<< sizeof(a) << endl; // 12 字节
cout<< sizeof(p) << endl; // 4 字节
计算数组和指针的内存容量
void Func(char a[100])
{
cout<< sizeof(a) << endl; // 4 字节而不是100 字节
}
34.类成员函数的重载、覆盖和隐藏区别?
答案:
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
华为笔试题
4.请问C++的类和C里面的struct有什么区别?
5.请讲一讲析构函数和虚函数的用法和作用。
6.全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的
?
IBM R&D C++ 考题
2。似乎是这样的:
class CA
{
public:
int i;
virtual ff(){i = 1};
void print(){printf("%d\n"),i};
}
class CB:public class CA
{
private:
int i;
public:
virtual ff(){i = 2};
//void print(){printf("%d\n"),i};
}
class CC:public class CB
{
private:
int i;
public:
virtual ff(){i = 3};
//void print(){printf("%d\n"),i};
}
int main()
{
CC * A = new CB();
A->ff();
A->print();
CC * B = (CC *)new CA();
B->ff();
B->print();
CC * C= (CC *)new CB();
C->ff();
C->print();
}
3。C++ 比c好的地方。(多选)
4。inline 函数的特点 (多选)
5。inline & 宏的不同 (多选)
6。什么叫做抽象
下面据说是华为公司的笔试题,其实我想它一次笔试不可能出这么多题,也许是多年笔试题的合集,或者也包括了其他公司的笔试内容。最近国际商用工程集团(
1.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值(3分)
int a = 4;
(A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++);
a = ?
答:C错误,左侧不是一个有效变量,不能赋值,可改为(++a) += a;
改后答案依次为9,10,10,11
2.某32位系统下, C++程序,请计算sizeof 的值(5分).
char str[] = “”
char *p = str ;
int n = 10;
请计算
sizeof (str ) = ?(1)
sizeof ( p ) = ?(2)
sizeof ( n ) = ?(3)
void Foo ( char str[100]){
请计算
sizeof( str ) = ?(4)
}
void *p = malloc( 100 );
请计算
sizeof ( p ) = ?(5)
答:(1)17 (2)4 (3) 4 (4)4 (5)4
3. 回答下面的问题. (4分)
(1).头文件中的 ifndef/define/endif 干什么用?预处理
答:防止头文件被重复引用
(2). #include 和 #include “filename.h” 有什么区别?
答:前者用来包含开发环境提供的库头文件,后者用来包含自己编写的头文件。
(3).在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”声明?
答:函数和变量被C++编译后在符号库中的名字与C语言的不同,被extern "C"修饰的变量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调用C 函数。C++提供了一个C 连接交换指定符号extern“C”来解决这个问题。
(4). switch()中不允许的数据类型是?
答:实型
4. 回答下面的问题(6分)
(1).
Void GetMemory(char **p, int num){
*p = (char *)malloc(num);
}
void Test(void){
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
请问运行Test 函数会有什么样的结果?
答:输出“hello”
(2).
void Test(void){
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str != NULL){
strcpy(str, “world”);
printf(str);
}
}
请问运行Test 函数会有什么样的结果?
答:输出“world”,因为free(str)后并未改变str所指的内存内容。
(3).
char *GetMemory(void){
char p[] = "hello world";
return p;
}
void Test(void){
char *str = NULL;
str = GetMemory();
printf(str);
}
请问运行Test 函数会有什么样的结果?
答:无效的指针,输出不确定
5. 编写strcat函数(6分)
已知strcat函数的原型是char *strcat (char *strDest, const char *strSrc);
其中strDest 是目的字符串,strSrc 是源字符串。
(1)不调用C++/C 的字符串库函数,请编写函数 strcat
答:
VC源码:
char * __cdecl strcat (char * dst, const char * src)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
(2)strcat能把strSrc 的内容连接到strDest,为什么还要char * 类型的返回值?
答:方便赋值给其他变量
7.C++中为什么用模板类。
答:(1)可用来创建动态增长和减小的数据结构
(2)它是类型无关的,因此具有很高的可复用性。
(3)它在编译时而不是运行时检查数据类型,保证了类型安全
(4)它是平台无关的,可移植性
(5)可用于基本数据类型
12.Linux有内核级线程么。
答:线程通常被定义为一个进程中代码的不同执行路线。从实现方式上划分,线程有两种类型:“用户级线程”和“内核级线程”。用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统中也可实现,但线程的调度需要用户程序完成,这有些类似 Windows 3.x 的协作式多任务。另外一种则需要内核的参与,由内核完成线程的调度。其依赖于操作系统核心,由内核的内部需求进行创建和撤销,这两种模型各有其好处和缺点。用户线程不需要额外的内核开支,并且用户态线程的实现方式可以被定制或修改以适应特殊应用的要求,但是当一个线程因 I/O 而处于等待状态时,整个进程就会被调度程序切换为等待状态,其他线程得不到运行的机会;而内核线程则没有各个限制,有利于发挥多处理器的并发优势,但却占用了更多的系统开支。
Windows NT和OS/2支持内核线程。Linux 支持内核级的多线程
13.C++中什么数据分配在栈或堆中,New分配数据是在近堆还是远堆中?
答:栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理
堆: 程序运行时动态申请,new 和 malloc申请的内存就在堆上
近堆还是远堆不是很清楚。
15函数模板与类模板有什么区别?
答:函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。
19 关于内存对齐的问题以及sizof()的输出
答:编译器自动对齐的原因:为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。
20 int i=10, j=10, k=3; k*=i+j; k最后的值是?
答:60,此题考察优先级,实际写成: k*=(i+j);,赋值运算符优先级最低
2、请阅读以下一段程序,并给出答案。
class A
{
public:
A(){ doSth(); }
virtual void doSth(){printf("I am A");}
};
class B:public A
{
public:
virtual void doSth(){ printf("I am B");}
};
B b;
执行结果是什么?为什么?
答:执行结果是I am A
因为b对象构造时调用基类A的构造函数A(),得此结果。
1、有一段文本,统计其中的单词数。例如:
As a technology , "HailStorm" is so new that it is still only known by its
code name.
注意:单词间的间隔不一定是一个空格。
答:可执行程序代码如下,假设该文本已存入text这个数组里。
void main()
{
char text[1000]={"As a technology , 'HailStorm' is so new that it is still only known by its code name."};
int i=0,count=0;
bool flag=true;
while (text[i]&&i<1000)
{
if (text[i]==' ')
{
flag=true;
}
else if (flag==true && ((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')))
{ // 前有空格,接着出现字母,表示出现一个单词。
count++;
flag=false;
}
i++;
}
cout<<count;
}
微软研究院笔试题目
1. 改错
#include <stdio.h>
#include <String.h>
class CBuffer
{
char * m_pBuffer;
int m_size;
public:
CBuffer()
{
m_pBuffer=NULL;
}
~CBuffer()
{
Free();
}
void Allocte(int size) (3) {
m_size=size;
m_pBuffer= new char[size];
}
private:
void Free()
{
if(m_pBuffer!=NULL)
{
delete m_pBuffer;
m_pBuffer=NULL;
}
}
public:
void SaveString(const char* pText) const
{
strcpy(m_pBuffer, pText);
}
char* GetBuffer() const
{
return m_pBuffer;
}
};
void main (int argc, char* argv[])
{
CBuffer buffer1;
buffer1.SaveString("Microsoft");
printf(buffer1.GetBuffer());
}
答:改正后
主要改正SaveString函数
将
void SaveString(const char* pText) const
{
strcpy(m_pBuffer, pText);
}
改为
void SaveString(const char* pText) (1)
{
Allocte(strlen(pText)+1); (2)
strcpy(m_pBuffer, pText);
}
原因:
(1) const成员函数表示不会修改数据成员,而SaveString做不到,去掉const声明
(2) m_pBuffer指向NULL,必须用Allocte分配空间才能赋值。
(3) 另外需要将Allocte成员函数声明为私有成员函数更符合实际
2.下来程序想打印“Welcome MSR Asia”,改正错误
#include <stdio.h>
#include <string.h>
char * GetName (void)
{
//To return “MSR Asia” String
char name[]="MSR Asia";
return name;
}
void main(int argc, char* argv[])
{
char name[32];
//Fill in zeros into name
for(int i=0;i<=32;i++)
{
name[i]='\0';
}
//copy “Welcome” to name
name="Welcome";
//Append a blank char
name[8]=" ";
//Append string to name
strcat(name,GetName());
//print out
printf(name);
}
答:改正后为
#include <stdio.h>
#include <string.h>
char * GetName (void)
{
//To return “MSR Asia” String
//char name[]="MSR Asia"; (1)
char *name=(char *)malloc(strlen("MSR Asia")+1);
strcpy(name,"MSR Asia");
return name;
}
void main(int argc, char* argv[])
{
char name[32];
//Fill in zeros into name
for(int i=0;i<=32;i++)
{
name[i]='\0';
}
//copy “Welcome” to name
//name="Welcome"; (2)
strcat(name,"Welcome ");
//Append a blank char
// name[8]=' '; (3)
//Append string to name
char *p=GetName(); (4)
strcat(name,p);
free (p);
//print out
printf(name);
}
原因:(1)在函数内部定义的变量在函数结束时就清空了,必须动态分配内存
(2)字符串赋值语句错误,应该用strcat
(3)该语句无效,可去掉
(4)定义一个指针指向动态分配的内存,用完后需用free语句释放
3.写出下面程序的输出结果
#include <stdio.h>
class A
{
public:
void FuncA()
{
printf("FuncA called\n");
}
virtual void FuncB()
{
printf("FuncB called\n");
}
};
class B: public A
{
public:
void FuncA()
{
A::FuncA();
printf("FuncAB called\n");
}
virtual void FuncB()
{
printf("FuncBB called\n");
}
};
void main(void)
{
B b;
A *pa;
pa=&b;
A *pa2=new A;
b.FuncA(); (1)
b.FuncB(); (2)
pa->FuncA(); (3)
pa->FuncB(); (4)
pa2->FuncA(); (5)
pa2->FuncB();
delete pa2;
}
答:
1.b.FuncA(); 输出
FuncA called
FuncAB called
2.b.FuncB();输出
FuncBB called
上两者好理解,直接调用类B的相应成员函数
3.pa->FuncA();输出
FuncA called 调用类A的FuncA()
4.pa->FuncB();输出
FuncBB called调用类B的FuncB(),原因是C++的动态决议机制,当基类函数声明为virtual时,指向派生类对象的基类指针来调用该函数会选择派生类的实现,除非派生类没有才调用基类的虚函数。还有一点注意的是:指向基类类型的指针可以指向基类对象也可以指向派生类对象,如pa=&b;
5. pa2->FuncA();
pa2->FuncB();输出
FuncA called
FuncB called
这也好理解,直接调用类A的相应成员函数
4.In the main() function, after ModifyString(text) is called, what’s the value of ‘text’?
#include <stdio.h>
#include <string.h>
int FindSubString(char* pch)
{
int count=0;
char* p1=pch;
while(*p1!='\0')
{
if(*p1==p1[1]-1)
{
p1++;
count++;
}
else
{
break;
}
}
int count2=count;
while(*p1!='\0')
{
if(*p1==p1[1]+1)
{
p1++;
count2--;
}
else
{
break;
}
}
if(count2==0)
return count;
return 0;
}
void ModifyString(char* pText)
{
char* p1=pText;
char* p2=p1;
while(*p1!='\0')
{
int count=FindSubString(p1);
if(count>0)
{
*p2++=*p1;
sprintf(p2, "%I", count);
while(*p2!= '\0')
{
p2++;
}
p1+=count+count+1;
}
else
{
*p2++=*p1++;
}
}
}
void main(void)
{
char text[32]="XYBCDCBABABA";
ModifyString(text);
printf(text);
}
答:我不知道这个结构混乱的程序到底想考察什么,只能将最后运行结果写出来是XYBCDCBAIBAAP
C++面试题(初级)
姓名______ 日期_______
1:写出输出
void fun(int i) {
cout<
}
static int value=i++;
int main() {
fun(0);
fun(1);
fun(2);
}
2:引用和指针之间有什么区别?
3:比较全局变量和静态变量,试说明两者有何异同.
4:分析代码,给出i,j,k的结果.
int i,j,k;
i=j=k=0;
if(++i||j++||++k) {}
5:说出如下const声明的含义:
1.const char* p
2.char const* p
3.char* const p
4.char A::fun() const;
6:编译下面的代码,会有什么结果?
1:
void fun(char);
void fun(char*);
int main()
{
fun(0);
}
2:
void fun(int);
void fun(int*);
int main()
{
fun(0);
}
7:请写出程序运行的结果
class A{
public:
A() { cout<<"A::A()"<
~A() { cout<<"A::~A()"<
};
class B{
public:
B() {cout<<"B::B()"<
~B() {cout<<B::~B()"<
};
class C:public B{
A a;
public:
C() {cout<<"C::C()"<
~C() {cout<<"C::~C()"<
};
A a;
int main()
{
C c;
}
8:请写出程序运行的结果
class A{
public:
A() {cout<<"A::A()"<
~A() {cout<<"A::~A()"<
};
class B{
public:
B(){cout<<"B::B()"<
~B(){cout<<"B::~B()"<
};
class C:public B{
public:
C():a(A()),b(B()){}
~C(){}
private:
B b;
A a;
};
int main()
{
C c;
}
9:请写出程序运行的结果
#include
using namespace std;
class base{
public:
virtual void print() const {cout<<"base::f()"<
};
class derived:public base {
public:
virtual void print() const {cout<<"derived::f()"<
};
void print(const base& obj)
{
obj.print();
}
int main()
{
base* pb1=new derived();
print(*pb1);
base* pb2=new base(*pb1);
print(*pb2);
base b=base(derived());
print(b);
delete pb1;
delete pb2;
return 0;
}
10:什么是抽象类?
11:什么时候需要使用虚拟析构函数?
12:抽象基类的抽象虚析构函数一定要有函数体吗? 为什么?
13:下面的代码是否有错误? 如果有错,请说明原因.
char* const s="hello";
s[0]='a';
14:分析如下代码是否存在问题
const char* hello() {return "hello world";}
int main()
{
const char* pc=hello();
cout<
}
15:分析下面代码,指出问题
class obj{};
1. obj& fun() {obj o;return o;}
2. obj* fun() {obj o;return &o;}
3. obj fun() {obj o;return o;}
16:什么是函数重载?
17:面向对象有哪三个要素?
18:什么是多态?C++如何实现多态?
19:构造函数没有返回值,那么如何得知对象是否构造成功?
20:编译一个C/C++程序通常有哪几个阶段?
21:请指出下面代码存在的问题
class CC{
int* m_pCount;
public:
void clear(){ if (m_pCount) delete m_pCount;}
CC(){m_pCount=new int;}
~CC() {clear();}
};
22:请指出如下代码的问题所在
void ex() {
throw exception("exception");
}
void fun() {
char* buf=new char[64];
ex();
delete[] buf;
}
THANKS !!!
致力为企业和个人提供合同协议,策划案计划书,学习课件等等
打造全网一站式需求
欢迎您的下载,资料仅供参考
可修改编辑
展开阅读全文