- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章C++面试常见问题整理汇总由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文总结讲述了C++面试常见问题。分享给大家供大家参考,具体如下:
1. 继承方式 。
public 父类的访问级别不变 protected 父类的public成员在派生类编程protected,其余的不变 private 父类的所有成员变成private 。
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
|
#include <iostream>
using
namespace
std;
class
base
{
public
:
void
printa()
{ cout <<
"base"
<< endl; }
protected
:
void
printhello()
{ cout <<
"helo"
<< endl; }
private
:
void
printnohello()
{ cout <<
"no hello"
<< endl; }
};
class
derived :
public
base
{
public
:
void
printb() { printhello(); }
// void printc() { printnohello(); } //printnohello是父类的私有函数,不可访问
};
int
main()
{
base a;
a.printa();
//a.printhello(); //printhello是类derived的protected函数,不可访问。
}
|
2. sizeof 和 strlen 的区别 。
① sizeof 是一个操作符,strlen 是库函数。 ② sizeof 的参数可以是数据的类型,也可以是变量,而 strlen 只能以结尾为‘\ 0‘的字符串作参数。 ③ 编译器在编译时就计算出了sizeof 的结果。而strlen 函数必须在运行时才能计算出来。并且 sizeof计算的是数据类型占内存的大小,而 strlen 计算的是字符串实际的长度。 ④ 数组做 sizeof 的参数不退化,传递给 strlen 就退化为指针了.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include <iostream>
#include <cstdlib>
#include <cstring>
using
namespace
std;
int
main()
{
int
a[] = {1, 2, 3, 4, 5};
cout <<
sizeof
(a) << endl;
//20
// cout << strlen(a) << endl;
char
b[] = {
'a'
,
'b'
};
cout <<
strlen
(b) << endl;
//6
cout <<
sizeof
(b) << endl;
//2
}
|
3. C中的 malloc 和C++中的 new 有什么区别 。
new、delete 是操作符,可以重载,只能在 C++中使用。 malloc、free 是函数,可以覆盖,C、C++中都可以使用。 new 可以调用对象的构造函数,对应的 delete 调用相应的析构函数。 malloc 仅仅分配内存,free 仅仅回收内存,并不执行构造和析构函数 new、delete 返回的是某种数据类型指针,malloc、free 返回的是 void 指针.
注意:malloc 申请的内存空间要用 free 释放,而 new 申请的内存空间要用 delete 释放,不要混用.
因为两者实现的机理不同.
4.1. c/c++中static 。
要理解static,就必须要先理解另一个与之相对的关键字auto,其实我们通常声明的不用static修饰的变量,都是auto的,因为它是默认的。auto的含义是由程序自动控制变量的生存周期,通常指的就是变量在进入其作用域的时候被分配,离开其作用域的时候被释放;而static就是不auto,变量在程序初始化时被分配,直到程序退出前才被释放;也就是static是按照程序的生命周期来分配释放变量的,而不是变量自己的生命周期;所以,像这样的例子:
1
2
3
4
5
|
void
func()
{
int
a;
static
int
b;
}
|
每一次调用该函数,变量a都是新的,因为它是在进入函数体的时候被分配,退出函数体的时候被释放,所以多个线程调用该函数,都会拥有各自独立的变量a,因为它总是要被重新分配的;而变量b不管你是否使用该函数,在程序初始化时就被分配的了,或者在第一次执行到它的声明的时候分配(不同的编译器可能不同),所以多个线程调用该函数的时候,总是访问同一个变量b,这也是在多线程编程中必须注意的! 。
static的全部用法:
1.类的静态成员:
1
2
3
4
5
|
class
A
{
private
:
static
int
s_value;
};
|
在cpp中必须对它进行初始化:
1
|
int
A::s_value = 0;
// 注意,这里没有static的修饰!
|
类的静态成员是该类所有实例的共用成员,也就是在该类的范畴内是个全局变量,也可以理解为是一个名为A::s_value的全局变量,只不过它是带有类安全属性的;道理很简单,因为它是在程序初始化的时候分配的,所以只分配一次,所以就是共用的; 。
类的静态成员必须初始化,道理也是一样的,因为它是在程序初始化的时候分配的,所以必须有初始化,类中只是声明,在cpp中才是初始化,可以在初始化的代码上放个断点,在程序执行main的第一条语句之前就会先走到那;如果你的静态成员是个类,那么就会调用到它的构造函数; 。
2.类的静态函数:
1
2
3
4
5
|
class
A
{
private
:
static
void
func(
int
value);
};
|
实现的时候也不需要static的修饰,因为static是声明性关键字;类的静态函数是在该类的范畴内的全局函数,不能访问类的私有成员,只能访问类的静态成员,不需要类的实例即可调用;实际上,它就是增加了类的访问权限的全局函数:void A::fun(int),
静态成员函数可以继承和覆盖,但无法是虚函数; 。
3.只在cpp内有效的全局变量:
在cpp文件的全局范围内声明:
1
|
static
int
g_value = 0;
|
这个变量的含义是在该cpp内有效,但是其他的cpp文件不能访问这个变量;如果有两个cpp文件声明了同名的全局静态变量,那么他们实际上是独立的两个变量; 。
如果不使用static声明全局变量:
1
|
int
g_value = 0;
|
那么将无法保证这个变量不被别的cpp共享,也无法保证一定能被别的cpp共享,因为要让多个cpp共享一个全局变量,应将它声明为extern(外部)的;也有可能编译会报告变量被重复定义;总之不建议这样的写法,不明确这个全局变量的用法; 。
如果在一个头文件中声明:
1
|
static
int
g_vaule = 0;
|
那么会为每个包含该头文件的cpp都创建一个全局变量,但他们都是独立的;所以也不建议这样的写法,一样不明确需要怎样使用这个变量,因为只是创建了一组同名而不同作用域的变量; 。
这里顺便说一下如何声明所有cpp可共享的全局变量,在头文件里声明为extern的:
1
|
extern
int
g_value;
// 注意,不要初始化值!
|
然后在其中任何一个包含该头文件的cpp中初始化(一次)就好:
1
|
int
g_value = 0;
// 初始化一样不要extern修饰,因为extern也是声明性关键字;
|
然后所有包含该头文件的cpp文件都可以用g_value这个名字访问相同的一个变量; 。
4.2 C中static有什么作用 。
① 隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,故使用static在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。 ② 保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和static变量。 ③ 默认初始化为0.其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。在静态数据区,内存中所有的字节默认值都是0×00,某些时候这一特点可以减少程序员的工作量.
5. 简述C\C++程序编译的内存情况分配 。
C、C++中内存分配方式可以分为三种:
(1)从静态存储区域分配:内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在。速度快、不容易出错,因为有系统会善后。例如全局变量,static变量等。 (2)在栈上分配:在执行函数时,函数内局部变量的存储单元都在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 (3)从堆上分配:即动态内存分配。程序在运行的时候用 malloc 或 new 申请任意大小的内存,程序员自己负责在何时用 free 或 delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活。如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,另外频繁地分配和释放不同大小的堆空间将会产生堆内碎块.
一个 C、C++程序编译时内存分为 5 大存储区:堆区、栈区、全局区、文字常量区、程序代码区.
6. 面向对象的三大特征 。
① 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。 ② 继承,是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”和“组合”来实现。 ③ 多态,简单的说,就是一句话:允许将指向子类类型的指针赋值给父类类型的指针。实现多态,有二种方式,覆盖,重载.
覆盖,是指子类重新定义父类的虚函数的做法。 重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同).
总结:作用 。
① 封装可以隐藏实现细节,使得代码模块化 ② 继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用 ③ 多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用.
7. 简述多态的实现原理 。
编译器发现一个类中有虚函数,便会立即为此类生成虚函数表vtable。虚函数表的各表项为指向对应虚函数的指针。编译器还会在此类中隐含插入一个指针 vptr指向虚函数表。调用此类的构造函数时,在类的构造函数中,编译器会隐含执行 vptr 与 vtable 的关联代码,将 vptr 指向对应的 vtable,将类与此类的 vtable 联系了起来。另外在调用类的构造函数时,指向基础类的指针此时已经变成指向具体的类的 this 指针,这样依靠此 this 指针即可得到正确的 vtable.
如此才能真正与函数体进行连接,这就是动态联编,实现多态的基本原理.
注意:一定要区分虚函数,纯虚函数、虚拟继承的关系和区别。牢记虚函数实现原理,因为多态C++面试的重要考点之一,而虚函数是实现多态的基础.
8. c++空类的成员函数 。
缺省的构造函数 缺省的拷贝构造函数 缺省的赋值运算符 缺省的析构函数 缺省的取址运算符 缺省的取址运算符const 。
注意:只有当实际使用这些函数的时候,编译器才会去定义它们.
9. 谈谈你对拷贝构造函数和赋值运算符的认识 。
两个不同之处:
① 拷贝构造函数生成新的类对象,而赋值运算符不能。 ② 由于拷贝构造函数是直接构造一个新的类对象,所以在初始化这个对象之前不用检验源对象是否和新建对象相同。而赋值运算符则需要这个操作,另外赋值运算中如果原来的对象中有内存分配要先把内存释放掉.
注意:当有类中有指针类型的成员变量时,一定要重写拷贝构造函数和赋值运算符,不要使用默认的.
10. 用 C++设计一个不能被继承的类 。
1
2
3
4
5
6
7
8
9
10
11
12
|
class
Base
{
private
:
Base() {}
~Base() {}
};
class
Derived :
public
Base
{
public
:
Derived() : Base() {}
~Derived() {}
};
|
C++ 中的流对象就是采用这样的原理。防止被赋值、复制.
11. 类成员的重写、重载和隐藏的区别 。
重写和重载主要有以下几点不同 。
① 范围的区别:被重写的和重写的函数在两个类中,而重载和被重载的函数在同一个类中。 ② 参数的区别:被重写函数和重写函数的参数列表一定相同,而被重载函数和重载函数的参数列表一定不同。 ③ virtual 的区别:重写的基类中被重写的函数必须要有 virtual 修饰,而重载函数和被重载函数可以被virtual 修饰,也可以没有.
隐藏和重写、重载有以下几点不同 。
① 与重载的范围不同:和重写一样,隐藏函数和被隐藏函数不在同一个类中 ② 参数的区别:隐藏函数和被隐藏的函数的参数列表可以相同,也可不同,但是函数名肯定要相同。当参数不相同时,无论基类中的参数是否被 virtual 修饰,基类的函数都是被隐藏,而不是被重写 。
说明:虽然重载和覆盖都是实现多态的基础,但是两者实现的技术完全不相同,达到的目的也是完全不同的,覆盖是动态绑定的多态,而重载是静态绑定的多态.
12. extern 有什么作用 。
extern 标识的变量或者函数声明其定义在别的文件中,提示编译器遇到此变量和函数时在其它模块中寻找其定义.
13. 引用和指针区别 。
① 引用必须被初始化,但是不分配存储空间。指针不必在声明时初始化,在初始化的时候需要分配存储空间 ② 引用初始化以后不能被改变,指针可以改变所指的对象 ③ 不存在指向空值的引用,但是存在指向空值的指针 。
14. 数组指针 。
1
2
3
4
5
6
7
8
9
10
11
|
#include <iostream>
using
namespace
std;
int
main()
{
int
a[5] = {1, 2, 3, 4, 5};
int
*ptr = (
int
*)(&a+1);
cout << *(ptr-1) <<
"\t"
<< *(ptr-2) << endl;
// 5 4
cout <<
"----------------"
<< endl;
int
*p = (
int
*)(a+1);
//2
cout << *p << endl;
}
|
15. const int *a 和 int * const a 区别 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int
main()
{
int
b = 3;
int
c = 4;
const
int
*p = &b;
//等价于 int const *p = &b;
p = &c;
//修饰值,指针可变
//*p = 5;//error 修饰值,值不可变
cout << *p << endl;
int
a = 5;
int
*
const
q = &a;
//修饰指针
//p = &c;//error修饰指针,指针不可变
*p = 5;
//修饰指针,值可变
}
|
希望本文所述对大家C++程序设计有所帮助.
最后此篇关于C++面试常见问题整理汇总的文章就讲到这里了,如果你想了解更多关于C++面试常见问题整理汇总的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
总览 数据库的数据存储有两种类型,一种是面向行的(row-oriented)数据库,另一种是面向列的(column-oriented )数据库。 面向行(事务型) 数据库 该类数据库是根据
starting from a joke 问:把大象放冰箱里,分几步? 答:三步啊,第1、把冰箱门打开,第2、把大象放进去,第3、把冰箱门带上。 问:实现spring事务,分几步? 答:三
在最近的一次采访中,我有这个问题。 这里有什么错误?我知道足够的 c#,但我看不到错误。可以吗? Class x { protected string t1; public int
我在面试中被要求设计一个文件系统,允许用户将自己的属性添加到文件和文件夹中。我刚刚说过要将属性添加到文件描述符并允许根据此属性标准搜索文件,以及添加此属性以显示在文件/文件夹详细信息中。 看起来面试官
我一直在面试,下面应该有什么问题? 我可以假设这是您无法检查类是否为空的问题,对吗?!谢谢! public class NiceActivity extends Activity { priv
给定一个数组,如何返回总和为偶数的对数? 例如: a[] = { 2 , -6 , 1, 3, 5 } 在这个数组中,偶数和的对数是(2,-6), (1,3) , (1,5), (3,5) 函数应返回
这个问题是在面试中被问到的 Assume you have a dictionary of words: (use if you have /usr/share/dict/words). Given
我被要求实现 invert(x,p,n) 返回 x 的 n 位开始于位置 p 反转(即 1 变为 0,反之亦然),其他不变。 我的解决方案是: unsigned invert(unsigned x,
有人问我这个问题:给定一个大小为 n 的 int 和 int sum 的数组,我需要返回数组元素的所有对,其总和等于 总和 std::vector > find(int* arr,size_t n,i
我在一次面试中遇到了这个问题。有一组对象与起始值和结束值相关联。与每个对象相关联的计数是具有较长开始时间和较短结束时间的其他对象的数量。所以我必须找到与每个对象关联的计数。 我提出了 O(n^2) 解
我今天在采访中被问到这个问题。我已经尝试了一种解决方案,但想知道是否有更好的方法来解决这个问题: 问题:我有一个包含 500,000 个元素的数组列表,这样数组列表的每个元素的值都与索引相同。例如:l
有一个包含白色单元格,黑色单元格和只有一个灰色单元格的矩阵,需要从 (0,0) 到 (N-1, N-1) 如果 Arra[N][N]约束:A。该路径应该只覆盖白色单元格并且应该通过灰色单元格。b.访问
给定一个正整数数组,找出排列的任意排列可以形成的最大值。我想知道是否有更好的数据结构可以为问题提供更优雅的解决方案。 import java.util.ArrayList; import java.u
我在面试中被问到以下问题(不幸的是我找不到比 N^2 更好的答案) 对于大小为 N 的 unsigned int 的给定数组 arr,对于每个元素(在索引 i 中)我应该返回一个元素在索引 j (j
极点:数组中左侧元素小于或等于它且右侧元素大于或等于它的元素。 示例输入 3,1,4,5,9,7,6,11 期望的输出 4,5,11 面试时被问到这个问题,要返回元素的索引,只返回第一个满足条件的元素
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我今天被问到这个问题,我知道答案很简单,但他让我一直到最后。 问题 编写程序删除存储在 ArrayList 中的偶数,其中包含 1 - 100。 我只是说哇 给你,这就是我的实现方式。 ArrayLi
我在一次采访中遇到了这个问题,完全被难住了。我能想到的唯一解决方案是将 currentAngle 存储在 NSArray 中以计算下一个角度。 问题:使用 iPhone 的指南针在屏幕上移动一个 35
我必须在接下来的几周内采访一些 C++ 候选人,作为公司最资深的程序员,我应该尝试弄清楚这些人是否知道他们在做什么。 那么有人有什么建议吗? 就我个人而言,我讨厌被留在房间里填写一些 C++ 问题,所
消息队列(MQ),一种能实现生产者到消费者单向通信的通信模型,这也是现在常用的主流中间件。 常见有 RabbitMQ、ActiveMQ、Kafka等 他们的特点也有很多 比如 解偶、异步、广播
我是一名优秀的程序员,十分优秀!