Last active
November 12, 2016 09:29
c++面试小题
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
c++ 缺省参数注意事项: | |
1.如果一个参数带有缺省值,那么它后边的所有参数必须都带有缺省值 | |
2.如果一个函数声明和定义分开,那么缺省参数只能放在声明中。因为编译器编译时看的是函数声明 | |
3.缺省参数避免和重载发生歧义 | |
c++ 中 ++i 和 i++的实现: | |
int operator++(); // 前++ | |
int operator++(int); // 后++ | |
用到哑元 | |
内联和宏的区别: | |
内联是编译器做的, 用函数的二进制代码替换函数调用语句,减少函数调用的时间开销。 | |
而宏是代码替换,且是预处理器处理的 | |
递归函数无法内联 | |
拷贝构造函数的原型: | |
A(const A& that); | |
必须用引用, 避免递归 | |
实现一个字符串的拷贝赋值运算符: | |
String& operator=(const String& that) { | |
if(&that != this) { | |
// char* str = new char[strlen(that.m_str)+1]; | |
// delete[] m_str; //和析构函数重复 | |
// m_str = strcpy (str, that.m_str); | |
String tmp(that); | |
swap(m_str, tmp.m_str); | |
} | |
} | |
swap交换后tmp.m_str就是该对象的m_str,这样temp在作用域结束时就被释放了,相当于旧的m_str释放,持有的是that的地址,也就是新值 | |
此函数注意: | |
1.避免自赋值 | |
2.避免直接new而泄露原来的内存 | |
3.防止new失败 | |
4.避免代码冗余 | |
引用: | |
void foo (int& x) { | |
cout << x << endl; | |
} | |
foo(100); // 错误, 把右值赋给了左值的引用, 把函数参数改为(const int& x)就对了 | |
异常: | |
我们throw的时候扔出去的是一个临时变量,但是catch的时候为什么用的是Exception&? | |
其实我们抛出的变量在第一个}之后被释放掉了,但是他会在全局区保留一个copy,之后所有的throw抛出的都是这个全局区的对象 | |
程序在catch的时候拿到的也是这个全局区的对象,而非局部变量的引用 | |
返回局部变量的引用: | |
int& bar (void) { | |
int a = 100; | |
return a; | |
} | |
t& fun (void) { | |
int b = 200; | |
return b; | |
} | |
int& a = bar(); | |
fun(); | |
cout << a << endl; //200, 所以不能返回局部变量的引用 | |
常函数为什么不能调用非常函数: | |
因为成员函数有个隐形的this参数, 常函数对应的是 const C* this, 而非常函数对应的是 C* this | |
用常函数调用非常函数等价于把 const C* this 赋给 C* this, 这是不允许的 | |
构造函数: | |
A a; 有可能调用哪些构造函数? | |
1.无参构造 | |
2.带有缺省值的有参构造函数 | |
编译优化: | |
class A{}; | |
A bar (void) { | |
A a; | |
cout << &a << endl; | |
return a; | |
} | |
int main(void) { | |
A a_m = bar(); | |
cout << &a_m << endl; | |
} | |
两次输出的地址是一样的. | |
bar函数他把自己栈里的临时变量a付给main函数里边的匿名变量, 然后再把匿名变量赋给a_m, 这要经过2次拷贝构造,浪费资源 | |
所以编译器直接把这个a该名为a_m; 所以两个输出的地址是一样的 | |
单例模式: | |
懒汉模式、饿汉模式 | |
饿汉模式是线程安全的, 因为程序加载进来后主进程会初始化静态变量然后创建线程, 这样线程里边拿到的是主进程创建出来的, 因为线程本身只是获取并不创建 | |
但是懒汉模式就存在线程安全问题, 因为对象的创建是在使用的时候创建的, 如果两个线程同时使用对象那么就会出现两个实例,所以可以加锁保护 | |
实现memcpy | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment