未经本人授权,禁止转载
这一部分会详细谈谈类
1. include" "与include< >的区别
include" "编译器首先查找当前工作的目录或源代码目录;
include< >编译器首先在存储标准头文件的主机系统的文件系统中查找。
2. 预处理器编译指令#ifndef
以前没有预处理过include"test.h"
时才执行中间的代码,可以很好的防止重复引用头文件。
#ifndef TEST_H_
#define TEST_H_
//...............
#endif
3. 类的构造函数
直接上代码比较直观,以下面的类为例。
class test
{
private:
int num;
string str;
public:
void func();
};
1. 没有构造函数编译器会隐式的声明一个默认构造函数
test x;
此时x中的num和str会被创建,但是没有任何值
2. 自己给出构造函数时,编译器不再隐式的声明默认构造函数
test(int t_num , const string & t_str); //在类内部声明
test::test(int t_num , const string & t_str) //定义,构造函数没有返回值
{
num = t_num;
str = t_str;
}
int main()
{
test x(12 , "hello world");
test y = test(12 , "hello world"); //两种完全等价,上面的是隐式调用,下面的是显式调用
test x; //!!!报错!!!因为没有了默认构造函数!!!
}
自定义了构造函数但是没有自行提供默认构造函数test x;
就会报错,定义默认构造函数有两种方法:
//1. 给构造函数的所有参数提供默认值
test::test(int t_num = 0 , const string & t_str = “err”)
{
num = t_num;
str = t_str;
}
//2. 使用函数重载来定义另一个构造函数——没有任何参数的构造函数
test::test()
{
num = 0;
str = "null";
}
3. 在使用初始化列表初始化类对象时,只要与某个构造函数的参数列表匹配即可
4. 构造函数的初始化列表语法
class example
{
private:
int x;
strinh str;
public:
example(int _x , const string & _str);
};
example::example(int _x , const string & _str) : x(_x) , str(_str) { } //个人觉得这样很装逼
5. 在构造函数中new的变量必须在析构函数中delete
6. 返回对象会调用复制构造函数,返回引用不会
4. 析构函数详解
最好是给出一个显式的析构函数,如果没有编译器将隐式的声明一个析构函数。
class test
{
private:
int num;
string str;
public:
test();
test(int t_num , const string & t_str);
~test();
void func();
};
析构函数的调用:如果是静态存储类对象,在程序结束时自动调用;如果是自动存储类对象,在代码块{ }结束时自动调用;如果是new的对象,在delete时自动调用。最好不要主动调用析构函数!!!
5. const成员函数
当成员函数不修改任何成员变量时,就应该把它定义为const成员函数以保证函数不会修改调用对象。
void func() const;
void test::func() const
{
//...........
}
6. this指针
this是一个指向调用对象本身的指针,*this是调用对象本身,注意二者的区别
7. 运算符重载
代码格式:operate运算符(),运算符必须是C++寓言已有的运算符。
class Test
{
private:
int x;
public:
Test(int _x = 0);
Test operate+(const Test & t);
};
Test::Test( int _x = 0)
{
x = _x;
}
Test Test::operate+(const Test & t)
{
Test sum;
sum.x = x + t.x;
return Test;
}
int main()
{
Test a(10);
Test b(20);
Test c;
c = a + b; //等效于c = a.operate+(b);
}
运算符重载的限制:
1.重载后的运算符必须至少有一个操作数是用户自定义的类型
2.使用运算符不能违反原来的句法规则,不能修改运算符的优先级
3.sizeof ,. ,.* ,:: ,?:等运算符不能重载
4.=,(),[],->只能在成员函数中重载
8. 友元函数
可以获得访问类成员权限的函数。
class Test
{
private:
int x;
public:
friend int func(); //在类中声明
};
int func() //定义与普通函数一样,不需要加限定符Test::
{
return 1;
}
func不是成员函数但是却有成员函数的权限,调用的时候也不是用成员运算符,而是和普通函数一样。
9. 类中的static
在类的成员变量前加上静态声明static,意味着不管创建多少类对象,他们都共同分享这个静态成员变量。
10. 隐式复制构造函数的危害
当构造函数中有new的变量时,最好给出显式的复制构造函数和重载一个复制运算符,因为隐式构造函数是浅复制,这会导致在析构函数被调用时容易出现问题。
网友评论