C++近期常见问题面试总结(一)

一、初始化列表:它的顺序应该和声明顺序一致,否则会引起初始化错误

class A{
private:
	const int a;
	double b;
	char c;
public:
	A(int a_, double b_, char c_) : a(a_), b(b_), c(c_){}
};

在对类对象做赋值时,调用的拷贝构造函数,赋值调用的赋值重载

class B{
private:
	A obj_A;
	int b;
public:
	//使用初始化列表的形式
	B(A a, int b_) : A(obj_A), b(b_){}
	//使用正常构造方法的形式
	B(A a, int b_){
		this ->a = a;
		b = b_;
	}
};

(1).在初始化列表进行初始化操作时,首先const成员和引用必须在初始化列表中进行初始化
(2).而缺省默认构造函数的类对象也必须在初始化列表中进行初始化,因为在构造函数中会先调用该类的默认构造函数
(3).对于有默认构造函数的类,初始化列表会调用赋值重载函数:operator=(),赋值重载函数会调用拷贝构造函数
而在构造函数中,会先调用默认构造函数,在调用赋值重载函数:operator=(),最后调用拷贝构造函数
因此初始化列表对于有默认构造函数的类对象会有更高的效率。

调用拷贝构造函数的三种情况,1.该对象作为参数时,2.该对象作为返回值时,3.初始化别的对象时。



二、空类
C++在底层实现时会保留一个字节,因为不能让对象不占内存。
由于现在的系统都是按字节编址,因为保留一个字节作为空类的对象。但字节里没有特定值。

编译器会自动默认生成的函数:
1.default constructor
2.default distructor
3.copy constructor
4.operator=()
5.operator&()
6.operator&()const
这几个函数虽然会默认生成,但是并不是说,肯定会生成它们
要是用不到,就不会生成

三、虚拟继承的实现
假设有以下继承体系


class Top{
		private :
			int a;
	};
	class Left : public Top{
		private :
			int b;
	};
	class Right public Top{
		private :
			int c;
	}
	class Bottom : public Left, public Right{
		private :
			int d;
	};
	//创建Bottom对象
	Bottom * ptr_Bottom = new Bottom();


那么在这个Bottom对象中的内存布局如下


Left::Top::a Left::b Right::Top::a Right::c Bottom::d
我们如果执行: Left * ptr_Left = ptr_Bottom;
操作是正常的,因为Bottom对象中首先继承left,因此left对象就在前面

而如果我们执行: Right * ptr_Right = ptr_Bottom;


四、this指针
C++对象模型中,成员函数是不在对象的内存中的,对象的内存中只存放虚函数表、成员变量

在调用成员函数时,怎么知道调用的哪个对象的成员函数,这一点是由this指针保证的
在成员函数的第一个参数,会默认有一个形参名为this的指针参数
哪个对象调用该成员函数,它的值就是谁的地址值
所以可以通过this->data来访问该对象的数据成员
而*this则表示该对象
所以说,对于this指针一个类只有一份
因为函数只有一份

const 用法:
1.const修饰普通变量,表示该变量为常变量,不能被修改
2.cosnt修饰指针,会优先修饰数据类型,否则才会修饰*
int const * a;表示a指向的是常量
const int * a;表示a指向的是常量
int * const a;表示a是一个常量指针,所指的对象不能被修改
3.const修饰引用,与修饰指针相同
4.const修饰函数:void fun()const;其实等价于:void fun(const className * this);
const修饰函数的功能是通过作用在this指针上完成的。因此const只能修饰成员函数,不能修饰static函数或普通函数
五、多态
多态分为编译时多态(重载)和运行时多态(多态)
1.函数重载: 由于C++对函数处理比较特殊,如void fun(int a, char b) 转换成fun_int_char这种形式,所以不同的参数类型和各种就可以形成不同的函数
这也是重载的定义,函数名称相同,函数的参数个数和参数类型不同,注意此处不要求返回值
多个重载的函数,实际形成的函数名会根据参数列表的不同而划分,是不是在编译的时候,调用不同的函数,调用时就会函数列表进行对比最终匹配到参数列表相同的函数
2.函数多态
对于含有虚函数的类,它的实例化对象中会有一个虚函数指针,该指针指向虚函数表。
函数会被放在符号表里
通过查符号表知道调用哪个函数,这都是编译过程完成的
虚函数,虚函数表类似于符号表,不过它存的是虚函数的地址
然后,调用哪个虚函数和符号表一样,都是查表的过程
所以,虚函数的引入其实是会拖慢效率的
父类的相同函数被定义为虚函数,该类的派生类的相同函数自动被虚化,无论有没有加virtual关键字,但是一般习惯是给子类加上virtual,为了阅读方便
而虚函数表一般都被放置于对象的头4个字节



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值