C++类知识总结
c++类
1、初始化const或引用类型数据成员的唯一机会是在构造函数初始化列表中。
2、使用成员初始化列表时成员初始化的次序:第一个成员首先被初始化、然后是第二个,依次类推。
构造函数初始化列表为类的基类和成员提供初始值,它并不指定初始化的执行次序。首先初始化基类,然后根据声明次序初始化派生类的成员。
3、派生类构造函数的要点:
- 首先创建基类对象
- 派生类构造函数应该通过成员初始化列表将基类信息传递给基类构造函数
- 派生类构造函数应初始化派生类新增的数据成员
4、派生类中虚函数的声明必须与基类中的定义方式完全匹配,但有一个例外:返回对基类的引用(指针)的虚函数。派生类中的虚函数可以返回基类函数所返回类型的派生类的引用(或指针)。
5、一旦函数在基类中声明为虚函数,他就一直为虚函数,派生类无法改变该函数为虚函数这一实时。派生类重定义虚函数时,可以使用virtual保留字,但不是必须这样做。
6、派生类对象由多个部分组成:派生类本身定义的(非static)成员加上由基类(非static)成员组成的子对象。
7、如果需要声明(但并不实现)一个派生类,则声明包含类名但不包含派生列表。下面的前向声明会导致编译时错误:
class Bulk_item : public Item_base;
8、可以在运行时确定virtual函数的调用,在编译时确定非virtual调用。
9、如果基类定义了static成员,则整个继承层次中只有一个这样的成员。无论从基类派生出多少个派生类,每个static成员只有一个实例。
10、派生类到基类的引用转换不同于对象转换:一个是将派生类对象转换为基类类型引用,一个是用派生类对象对基类对象进行初始化或赋值。
11、在基类和派生类中使用同一名字的成员函数,其行为与数据成员一样:在派生类作用域中派生类成员将屏蔽基类成员。即使函数原型不同,基类成员也会被屏蔽。(注意与重载的区别)
12、在函数形参表后面写上=0以指定纯虚函数。
13、含有一个或多个纯虚函数的类是抽象基类,抽象基类不能被实例化。
14、如果方法是通过引用或指针而不是对象调用的,它将确定使用哪一种方法。如果 没有使用关键字virtual,程序将根据引用类型或指针类型选择方法;如果使用了virtual,程序将根据引用或指针指向的对象的类型来选择方法。(动态绑定)
15、对于基类,即使它不需要析构函数,也应提供一个虚析构函数,这样做是为了确保释放派生对象时,按正确的顺序调用析构函数。
如果析构函数不是虚的,则将只调用对应于指针类型的析构函数。
16、关键字virtual只用于类声明中,而不用于方法定义中。
17、方法的行为应取决于调用该方法的对象。这种较复杂的行为称为多态——具有多种形态,即同一个方法的行为随上下文而异。有两种机制实现多态共有继承:
- 在派生类中重新定义基类的方法。
- 使用虚方法
18、class Dwelling
{
public:
virtual void showperks(int a) const;
...
};
class Hovel : public Dwelling
{
public:
virtual void showperks() const; //此处不是重载,而是重新定义
...
}
重新定义不会生成函数的两个重载版本,而是隐藏了接受一个int参数的基本版本。总之,重新定义继承的方法并不是重载。如果在派生类中重新定义函数,将不是使用相同的函数特征标覆盖基类声明,而是隐藏同名的基类方法,不管参数特征标如何。
经验:
- 如果重新定义继承的方法,应确保与原来的原型完全相同,但如果返回类型时基类引用或指针,则可以修改为指向派生类的引用或指针。这种特性被称为返回类型协变,因为允许返回类型随类类型的变化而变化。
- 如果基类声明被重载了,则应在派生类中重新定义所有的基类版本。
19、下述情况将使用复制构造函数:
- 将新对象初始化为一个同类对象
- 按值将对象传递给函数
- 函数按值返回对象
- 编译器生成历史对象
20、函数不能返回在函数中创建的临时对象的引用,因为当函数结束时,临时对象将消失,因此这种引用将是非法的。在这种情况下,应返回对象,以生成一个调用程序可以使用的副本。
21、使用const:
- 可以确保 方法不能修改参数:
Start:Start(const char *){...}
- 可以使用const来确保方法不能修改调用它的对象:
void Star::show() const {...} //这里const表示const Star *this,而this指向调用它的对象