1、类的默认函数
目前c++11的规则中,如果声明一个类什么都不写,但在使用中又使用了这些函数,编译器是会默认帮助生成以下函数的,包括
默认构造函数
析构函数
复制构造函数 (没有声明复制构造,且代码中调用了复制构造)
复制赋值函数
移动构造函数 (没有声明复制构造,没有声明析构,没有声明移动构造,且代码中使用了移动构造)
移动赋值函数
取址运算符和
取址运算符 const
注意,虽然复制构造,复制赋值和析构没有必须的关联关系,不会因为自定义了复制构造,就无法靠编译器自动生成复制赋值,但这三者在资源创建和回收应该有管理依赖关系,如果其中一个自定义了,最好还是自定义其他两个
所以如果自己类中的资源需要特殊处理,最好是自己定义这些构造赋值函数,
一般来说,需要以下的自定义函数
class Base {
public:
Base(); // 默认构造函数
~Base(); // 析构函数
Base(const Base & rhs); // 复制构造函数(有些地方也叫拷贝构造函数)
Base & operator=(const Base & rhs); // 复制赋值函数
Base (Base && rhs); // 移动构造函数
Base & operator=( Base && rhs); // 移动赋值函数
Base * operator&(); // 取址运算符
const Base * operator&() const; // 取址运算符 const
};
2、strlen和sizeof的区别
strlen是一个字符串中从起始位置遇到/0停止的走过个数
字符串末尾会自动加/0,比如char* pStr = “abcdefg”末尾有/0,char a[3] = "22",也有/0,但是char a[3] = "222”就没有了,会报错,因为数组大小不够。
1、char *test="test" 编译器会在字符串后面自动添加结尾符,所以结果为:4
2、char test[]="test" 编译器会在字符串后面自动添加结尾符,所以结果为:4
3、char test[]={"test"} 编译器会在字符串后面自动添加结尾符,所以结果为:4
4、char test[6]={'t','e','s','t'} 当定义的数组长度大于字符串长度时,编译器会在字符串后面自动添加结尾符,所以结果为:4
但是:char test[4]={"test"}这样不能编译通过,因为默认"test"字符串占5个字符的长度!
5、char test[4]={'t','e','s','t'}或char test[]={'t','e','s','t'} 这种情况下因为不管是数字长度缺省还是刚好填充字符个数,编译器都不会添加结尾符,所以这两种情况得到的结果不确定!
6,、C风格的字符串个string类赋值的时候:char* test="test";string str(test);或string str=test时,str.size()的值也是4(string的末尾也有‘\0’);
1、char* pStr = “abcdefg”
strlen(pStr) = 7 // pStr的字符串末尾g后面有/0
sizeof(pStr) = 4 // 这里是指针的大小
sizeof(*pStr) = 1 // 这里是“a”的大小
2、char cStr[] = “abcdefg”
strlen(pStr) = 7 // 不算/0
sizeof(pStr) = 8 // 算/0
3、extern作用
1、extern c+函数名。告诉编译器用c风格函数去编译,而不是c++
2、在.h中extern声明,在cpp中定义,然后在其他文件中包含.h使用;这种情况下,extern加不加无所谓,但是最好加
3、extern代替include.h,不包含.h,但是只能访问.h中有的变量或者函数,extern谁,链接谁
4、static作用
1、限制全局,实现只有当前文本访问:如果一个全局变量被static修饰,变成静态全局变量,那么该变量只能当前文本能开或者包含了该变量的文本。比如static变量在test1.h,那么test2.cpp中就不能通过extern访问该变量,如果include test1,那么就可以访问
2、类中成员变量或者成员函数如果被static修饰的话,那么他们会保存到全局区,所有该类的对象,只有一份该成员函数和变量,他们共享。非类静态能访问静态,静态不能访问非静态。
3、静态局部变量