c++面试总结

一. C++空类的字节数

C++标准规定类的大小不为0,空类的大小为1当类不包含虚函数和非静态数据成员时,其对象大小也为1。 如果在类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针指向虚函数表VTable,在32位机器上,一个对象会增加4个字节来存储此指针,它是实现面向对象中多态的关键。而虚函数本身和其他成员函数一样,是不占用对象的空间的。 我们来看下面一个例子:

class A{};
class b{
   char ch;
   void func(){}
};
class C{
   char ch1; //占用1字节
   char ch2; //占用1字节
   virtual void func(){}
};
class D{
   int n;
   virtual void func(){}
};

则sizeof(A())=1 (空类大小为1),sizeof(B())=1 (包含一个char类型的非静态成员变量,普通成员函数不占用内存), sizeof(C()) = 8 (对象c实际上只有6字节有用数据,但是按照上面第二点编译器优化,编译器将此扩展为两个字,即8字节)
综上所述:一个类中,虚函数,成员函数(包括静态和非静态)和静态数据成员都不占用类的存储空间。对象大小= vptr(指向虚函数的指针,可能不止一个,这个很难确定,不过试过,类中定义了一个virtual函数,仍然为占用4个字节) + 所有非静态数据成员大小 + Aligin字节大小(依赖于不同的编译器)

二. C++空类默认产生哪些成员函数

一共有六个,分别是

class A{
public:
	A(){}; //默认构造函数
	A(const A&){}; //默认拷贝构造函数
	~A(){}; //析构函数
	A& operator=(const A&){}; //赋值运算符重载函数
	A* operator&(); //取址运算符
	const A* operator& () const; // 取址运算符const
};

三. C++ const的用法

转载这篇博客

四. 为什么C++支持函数重载,而C语言不支持

  1. 函数重载
    所谓的函数重载就是在一组同一个作用域类,一组函数的函数名相同,参数列表不同(类型不同/个数不同),返回值可同可不同。
  2. 实例分析
    比如声明一个函数 void func(int x, int y),在C语言中,编译器进行编译之后,在库中的名字为_func;在C++中,编译器进行编译后名字为_func_int_int
    再来看另一个函数的声明void function(float x,float y),在C语言中,编译器进行编译之后,在库中的名字为_func;在C++中,编译器进行编译后名字为_func_float_float
    所以,编译器在链接阶段,都是找到相应的函数名,进行链接。在C语言中,两个函数的名字一样,就会在链接时报错。在C++中,两个函数饿名字不相同,就不会报错。
  3. 结论
    C语言,在编译之后的函数标识是函数本身,就会存在两个同名函数。C++,在编译之后的函数标识是函数名+参数(c++有函数名修饰规则,函数名+类型一起决定)

五. C++ static的用法

  1. static修饰全局变量
    (1)当同时编译多个文件时,所有未加static的全局变量和函数具有全局可见性其它文件也可以访问
    (2)未加static的全局变量,在符号表中是global符号,要参与符号解析;加了static之后,是local符号,其他目标文件不可见,只在当前文件中可见,不参与符号解析过程。所以多个源文件可以定义同名的static全局变量,不会产生重定义错误。
  2. static修饰局部变量
    修饰局部变量时,使它放在.data 或者.bss段(静态区),默认初始化为0,初始化不为0放在.data段,没有初始化或初始化为0放在.bss段。其生命周期是整个程序的声明周期。
    在这里插入图片描述
  3. static修饰普通函数
    修饰普通函数时,和修饰全局变量一样。函数经过编译产生一个函数符号,被static修饰后,就变为local符号,不参与符号解析,只在本文件中可见。
  4. static修饰类的成员变量
    修饰类的成员变量时,就变成静态成员变量,不属于对象,属于类。不能在类的内部初始化,类中只能声明,定义需要在类外类外定义时,不需要加static关键字,需要加类名作用域
  5. static修饰类的成员函数
    修饰类的成员函数时,变成静态成员函数,不属于对象,属于类。形参不会生成this指针仅能访问类的静态数据和静态成员函数。调用不依赖对象,所以不能作为虚函数。用类名作用域调用。

五. 其它问题

参考链接

六. 进程与线程

参考链接

七. 内联函数

参考链接

八. 左值引用与右值引用

当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的对象,即左值持久,右值短暂。参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值