C++初级之基本知识
2010-11-02 08:59:37 来源:WEB开发网1. 类是具有固定数目元素的集合。类是一种把数据和数据上的操作组合在一起的一个独立单元,本质上是一种特殊的数据类型,本身不占存储空间。每个类对象只对数据成员分配存储空间。C++编译器为每个成员函数只产生一个物理拷贝。属于同一个类的所有对象都使用相同的成员函数拷贝。因此在画类图的时候,应该画出所有该类的所有成员(成员函数和变量);而在画对象时,只画出该对象的成员变量。类的成员变量可以完全表征该类对象的属性,只要类的设计满足完整性。类的接口(成员函数)仅仅访问和修改类对象自身的变量(属性)。
2. 私有成员不能在类的范围(定义)之外被访问,这些成员属于隐藏消息,只有在类的定义过程当中被使用,对外并不公开,也就无法被访问。
3. 公有成员可以在类的范围(定义)之外被访问。即可以通过类对象或是类指针对这些成员进行访问。正是这些公有成员(一般是成员函数,成员变量最好不是公有)实现类和外部世界的交互性。
4. 类的定义:需要哪些属性?(通过成员变量来体现)对外需要哪些(功能)接口?通过成员函数来实现。一般情况下,可以通过类的接口来访问或是修改类的属性(成员变量)。显然,由于用于交互的接口目标是在于访问和修改类的属性,因此这些接口的参数肯定不是类的属性,而是外部世界的参数。具体需要哪些属性和接口,依能够完整实现要求而定,即类设计的完整性。
5. 在类的定义过程当中。声明的变量不能进行初始化。正因如此,类一定要有构造函数。默认构造函数无参数。
6. 类的定义仅仅是一种数据类型的声明,不涉及存储分配。仅当使用类声明类变量(对象)时,才会分配存储空间。这一点和内置的数据类型一样。正是由于类仅仅是一种特殊的数据类型,并不占任何存储空间,因此类的定义中,变量是不能被初始化的。这也就是为什么在类的继承过程当中基类也必须在派生类的析构函数头部初始化(触发初始化,使用类名,此时并没有具体的类对象);为什么在类的组合过程中,作为成员变量的类对象也是不能被初始化的也必须在新类的析构函数头部初始化(使用类对象名)。
7. 类对象进入其作用域(类对象被创建)时,构造函数自动执行;类对象退出其作用域(类对象被释放)时,析构函数被自动执行。构造函数和析构函数是两个及其特殊的函数:没有类型的函数,既没有返回值,又不是void函数。因此他们不能被其他成员函数调用,也不能被类对象访问。只能是自动的执行。但是他们却可以调用类的成员函数,即他们可以访问类中的任意成员:函数和变量(目标就是初始化成员变量)。
8. 继承是”is-a”的关系;组合是”has-a”的关系。继承和组合是关联两个类或多个类的有效方法。
9. 派生类不能访问基类的私有成员。因为在类的设计中,消息隐藏是重要的。只要类的设计完整正确,使用者完全可以通过类的接口和类进行交互。类的这种封装特性,简化了类间的关联,增强了类的独立性,有利于开发。当然派生类的设计者要明确派生类所具有的属性:基类具有的属性以及派生类新增的属性。派生类对外提供的接口当中,必须能够使外界可以访问和修改这些属性。所有的类在设计上都必须是完整的。
10. 类的受保护成员。受保护成员的可访问性界于公有成员和私有生员之间。派生类可以直接访问基类的受保护成员。可以说受保护成员完全是为继承而设计的。对于派生类而言,不管是公有继承、受保护继承,还是私有继承,派生类均可以直接访问基类的共有成员和受保护成员,而基类的私有成员对外总是封闭的。公有继承、受保护继承,私有继承的区别仅仅在于:由基类继承而来的共有成员和受保护成员在派生类中就体现为何种属性而已:共有继承不改变基类成员在派生类中的属性;受保护继承的话,基类的共有成员和原有的受保护成员在派生类中均成为受保护成员;对于私有继承,基类的所有成员在派生类中将全部为私有成员。
11. 派生类中重定义的函数和基类函数具有相同的函数名称和参数列表。但是如果派生类的函数仅仅和基类的函数名称相同,而参数列表不同,这就不是重定义,而是派生类的函数重载。
12. 派生类的构造函数必须能够触发基类的析构函数,除非想使用基类的默认构造函数(无参数列表)。C++派生类构造函数的函数头中指定调用基类的析构函数。
13. 在面向对象程序设计中,对象是基本的实体;在结构化程序设计中,函数是基本实体。在面向对象程序设计中,调试对象;在结构化程序设计中,调试函数。在面向对象程序设计中,程序是相互关联的对象集合;在结构化程序设计中,程序是相互关联的函数集合。在C++中,对象仅仅是类的示例,因此C++程序设计的本质就是类的设计。
14. 面向对象程序设计的三个基本特征:
封装:把数据和数据上的操作组合在一个独立单元中的能力;
继承:在现有的对象基础上创建新的对象的能力;
多态:使用相同个的表达式指定不同操作的能力。在C++中函数名称和运算符重载支持多态;模板支持参数多态机制;继承中使用虚函数支持多态机制。
15. 浅拷贝:两个或是多个相同类型的指针指向同一个内存地址,即它们指向同一个数据;深拷贝:两个或是多个相同类型的指针指向各自内存地址。在含有指针数据成员的类中,要防止浅拷贝(类对象的值拷贝),即没有给不同的对象的指针变量分配不同的地址空间。显然这样的情况,类的对象不能被很好的区分,同时容易出现错误。常见的赋值运算符、拷贝构造函数等(涉及类中的指针数据成员操作),都需要给新的对象的指针分配新的地址空间,并对这些地址空间赋值。
16. 自动执行拷贝构造函数的情况:1)使用其他现存的对象的值声明和初始化新对象时。2)对象作为值参数传递给函数时。(少见,一般类不使用值传递)。
17. 一般形参和实参应该一致。但是,对于类,C++允许用户将派生类的对象传递给基类类型的形参(值参数)。这是因为:派生类必然含有基类的所有成员,也就是基类的所有操作派生类都含有。反之,若形参是派生类类型,那么基类是不能传递给它的。因为基类仅仅是派生类的子集。这样的传递存在一些问题,见下一条。
18. 编译时绑定,即静态绑定:在编译时,调用指定的函数所必须的代码是由编译器指定的,也就是编译器根据形参的类型来编译相应的函数,比如函数重载、函数模板、类模板,对于类参数,则编译器根据类的类型编译相应的类成员函数。根据类指针类型编译相应的类成员函数。
19. 运行时绑定,即动态绑定:在编译时,编译器并不产生调用函数的代码,而只是提供必要的信息,使得运行时系统能产生实际的代码来调用相应的函数。C++中通过虚函数机制来实现动态编译。即程序根据实际运行过程中,函数的参数类型来产生相对应的函数代码。这种机制在将派生类的对象传递给基类类型的形参的函数调用中特别有用。同时需要注意,要使虚函数有效,形参必须是基类的引用或是指针,如果是值参数,那么由于传递过程是值拷贝,也就是自动调用基类的拷贝构造函数把派生类的中包含的基类成员变量拷贝给基类对象而已,因此函数内部的操作也仅仅是对派生类的基类的操作而已。
更多精彩
赞助商链接