一、学习笔记
1.在C语言中,结构体是不能有函数的;但在c++中,结构体是可以有函数的,称为成员函数。
2.class和struct最重要的不同是在成员访问控制方面有所差异:struct默认public,class默认private。
3.在定义类时,也不要忘记在最后加分号“;”。
4.析构函数不允许带参数。
一个类只能有一个析构函数。
5.构造函数中为对象分配内存空间(堆内存):pName = new char[20];
析构函数中释放内存:delete[] pName;
6.函数重载原则:调用时系统能分辨出该用哪个:参数类型或个数不同
常见错误:
(1)void output();和int output(); //只有返回值不同不叫重载,如a.output()不知道该用哪个
(2)void output(int a,int b=5);void output(int a);//参数个数不同,但第二个有默认参数,a.output(1)不知道该用哪个
7.void input(int x,int y)//改为int a,int b;策略一
{
x=x;//改为this->x=x;策略二
y=y;//改为this->y=y;
}
8.调用子类时,父类会在子类构造前构造,会在子类析构后析构。
问题:父类中构造函数有参数,在调用子类时,会出现错误:调用子类会先构造父类,这样未初始化父类中的参数。
解决:在构造子类时,显示的调用父类的带参数的构造函数:
(子类中)public:fish():animal(40,30){子类构造函数}
推广:这种初始化方式,还常用来对类中的常量(const)进行初始化:
public: point:x(0),y(0);
private:const int x; const int y;
9.子类型转为父类型不用强制转换。
10.c++的多态性是通过迟绑定技术来实现的。父类中函数用virtual修饰,c++编译器在编译时就会对该函数采用迟绑定技术,这个函数会根据对象的类型来确认调用的是哪个函数。
多态性用一句话来概括:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时会根据对象的实际类型调用相应的函数。
11.纯虚函数:virtua()=0;
凡是含有纯虚函数的类叫做抽象类。
这种类不能用于声名对象,只能用于派生类。
在派生类中必须完全实现来基类的纯虚函数,否则,派生类也变成了抽象类。
12.覆盖与隐藏
父类子类中两函数AB,函数名与参数列表完全一样,且A有virtual修饰==>覆盖。且B函数也为虚函数,即使无virtual修饰。
父类子类中两函数AB,函数名与参数列表完全一样,且A没有virtual修饰==>隐藏。
父类子类中两函数AB,函数名相同但参数列表不同,不管有无virtual修饰==>A都将被隐藏
13.覆盖与隐藏是在父类和子类中;重载是在同一个类中。
14.引用 、指针
(1)我们很少使用引用,因为引用变量和原变量都可以操作同一块地址,再这样容易出问题。
(2)在调用函数传递参数时,我们经常使用指针传递,因为:一、这样可以避免参数占用内存过大时的复制;二、为了一些特殊用法。
(3)使用引用作为形参也能完成指针的功能:
【例】change(a,b);//这时如果用指针(change(&a,&b);)的话容易让人误会,不知道是要交换地址还是交换值
void change(int& a,int& b) //对xy起别名,引用起到跟指针一样的作用。
{//可以积累这个小片段,用于交换ab值。
a=a+b;
b=a-b;
a=a-b;
}
15.避免头文件的重复定义
问题:先说结论:会造成重复定义:比如c.cpp中包含a.h和b.h,而b.h中也包含a.h。这样在编译c.cpp时,已经知道了a.h中有d类的定义,而在b中又有a.h,又知道了d类的定义,这样就造成了重复定义。
解决:a.h中做这样修改:
#ifndef A_H_H
#define A_H_H
class d
{
};
#endif
16.(详见文章《深入理解计算机系统》学习笔记:1.计算机系统漫游)
编译预处理==》编译==》链接