《C++ Primer Plus》读书笔记之八—对象和类

时间:2023-11-11 20:56:38

第十章 对象和类

    1、面向对象编程(OOP)的特性:抽象、封装和数据隐藏、多态、继承、代码的重用性。

  2、指定基本类型完成了3项工作:①决定数据对象需要的内存数量。②决定如何解释内存中的位(long和float再内存中用的位数相同,但将它们转化为数值的方法不同)。③决定可使用数据对象执行的操作或方法。注:对于内置类型来说,有关操作的信息被内置到编译器中。但在C++中定义用户自定义的类型时,必须自己提供这些信息。

  3、使用类对象的程序都可以直接访问公有部分,但只能通过公有成员函数或友元函数来访问对象的私有成员。因此,公有成员函数是程序和对象的私有成员之间的桥梁,提供了对象和程序之间的接口。

  4、防止程序直接访问数据被称为数据隐藏。类设计尽可能将公有接口与实现细节分开。公有接口表示设计的抽象组件。将实现细节放在一起并将它们与抽象分开被称为封装。

  5、类成员的数据项通常放在私有部分,组成类接口的成员函数放在公有部分,否则就无法从程序中调用这些函数。

  6、类和结构的唯一区别是:结构默认访问类型是public,而类为private。

  7、类成员函数的特殊特征:①定义成员函数时,使用作用域解析操作符(::)来标识函数所属的类。②类方法可以访问类的private组件。

  8、类方法的完整名称中包括类名。而省略类名的简单成员函数名是全名的缩写,它只能在类作用域中使用。

  9、定义位于类声明中的函数都将自动成为内联函数。类声明常将短小的成员函数作为内联函数。

  10、内联函数的特殊规则要求在每个使用它们的文件中都对其进行定义。确保内联定义对多文件程序中的所有文件都可用、最简单的方法是:将内联函数定义放在定义类的头文件中。

  11、调用成员函数时,它将使用被用来调用它的对象的数据成员。

  12、所创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员。但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。

  13、类构造函数,专门用于构造新对象,将值赋给它们的数据成员。构造函数没有返回值。

  14、构造函数的参数表示的不是类的成员,而是赋给类成员的值。因此,参数名不能与类成员相同。

  15、C++提供两种使用构造函数初始化对象的方式:①显式的调用构造函数:Stock food=Stock("abc",250,1.25);②隐式的调用构造函数:

Stock food("abc",250,1.25);③动态创建类对象:Stock *food=new Stock("abc",250,1.25);在这种情况下,对象没有名称,但可以使用指针来管理该对象。

  16、无法使用对象来调用构造函数,因为在构造函数构造出对象之前,对象是不存在的。因此构造函数被用来创建对象,而不能通过对象来调用。

  17、默认构造函数是在未提供显式的初始化值时,被用来创建对象的构造函数。例如:Stock food;将调用默认构造函数(Stock ::Stock(){})。如果没有提供任何构造函数,则C++将自动提供默认构造函数,它是默认构造函数的隐式版本,不做任何工作。

  18、当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数。为类定义了构造函数后,就必须为它提供默认构造函数。如果提供了非默认的构造函数,但没有提供默认构造函数,则Stock food;将出错!!

  19、定义默认构造函数的方式有两种:①给已有的构造函数的所有参数提供默认值:Stock(const char* co="abc",int n=0);②通过函数重载来定义另一个构造函数——一个没有参数的构造函数:Stock();注:由于只能有一个默认构造函数,因此不要同时采用这两种方式。默认构造函数可以没有任何参数,如果有,则必须给所有参数都提供默认值。

  20、下面几种形式将调用默认构造函数:①Stock a;②Stock a=Stock();③Stock *a=new Stock;注:Stock a();a()是一个返回Stock对象的函数。隐式的调用默认构造函数时,不要使用圆括号。

  21、由于在类对象过期时析构函数将自动被调用,因此必须有一个析构函数。如果没有提供析构函数,编译器将隐式的声明一个默认析构函数,并在发现导致对象被删除的代码后,提供默认析构函数的定义。

  22、C++编译器有两种方式来执行Stock food=Stock("abc",250,1.25);①一种方式和Stock food("abc",250,1.25);完全相同。②另一种方式是允许调用构造函数来创建一个临时对象,然后将该临时对象复制到food,并为临时对象调用析构函数。

  23、在默认情况下,将一个对象赋给同类型的另一个对象时,C++将源对象的每个数据成员的内容复制到目标对象中相应的数据成员中。

  24、构造函数不仅仅可用于初始化新对象!!例如stock1对象已经存在,则stock1=Stock("abc",250,1.25);说明,不是对stock1进行初始化,而是将新值赋给它。这是通过让构造函数创建一个新的、临时的对象,然后将其内容复制给stock1来实现的。随后程序调用析构函数以删除该临时对象。

  25、如果类对象不修改调用对象,就应该将成员函数声明为const:void show() const;(类内声明)void stock::show() const(类定义)。以这种方式声明和定义的类函数被称为const成员函数。

  26、接受一个参数的构造函数允许使用赋值语句来将对象初始化为一个值:Classname object=value;

  27、当有时候类成员函数涉及到两个对象时,需要使用this指针。

  28、有如下的类成员函数:const Stock & top(const Stock & s) const;该函数隐式的访问调用该函数的对象,而显式的访问形参所引用的对象。括号中的const表明,该函数不会修改被显式地访问的对象;而括号后的const表明。该函数不会修改被隐式的访问的对象。由于函数返回两个const对象之一的引用,因此返回类型也应是const引用。

  29、this指针指向用来调用成员函数的对象(this被作为隐藏参数传递给方法)。

  30、对象数组:Stock fun[4];// 包含4个类对象的数组。可以用构造函数来初始化数组元素。在这种情况下,必须为每个元素调用构造函数。例如:

 Stock fun[4]={Stock("abc",250,1.25),Stock("abd",25,1.25),Stock("bcd",2500,1.25),Stock("dce",50,1.25)};如果类包含多个构造函数,则可以对不同的元素使用不同的构造函数。

  31、初始化对象数组的方案是,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中。因此,要创建类对象数组,则这个类必须有默认构造函数。

  32、修改类的私有部分和实现文件属于实现更变;修改类的公有部分属于接口变更。实现变更改变了类的内部工作原理,接口变更改变了使用类的人可用的编码方式。

  33、可以将一个类的对象用作另一个类的成员。

  34、类作用域:在类中定义的名称(如类数据成员名和类成员函数名)的作用域都为整个类,作用域为整个类的名称只在该类中是已知的,在类外是不可知的。类作用域意味着不能从外部直接访问类的成员,要调用公有成员函数,必须通过对象。

  35、在类声明或成员函数定义中,可以使用未修饰的成员名称。构造函数名称在被调用时,才能被识别,因为它的名称与类名相同。在其他情况下,使用类成员时,必须根据上下文使用直接成员操作符(.)、间接成员操作符(->)或者作用域解析操作符(::)。

  36、在类中声明常量的两种方式:①在类中声明一个枚举:enum {len=30};注意,用这种方式声明枚举并不会创建数据成员。也就是说,所有对象中都不包含枚举。len只是一个符号名称,在作用域为整个类的代码中遇到它时,编译器将用30来替换它。②使用static:static const  int len=30;注:只能为int或枚举的静态常量,不能存储double常量。这将创建一个名为len的常量,该常量将于其他静态变量存储在一起,而不是存储在对象中。它被所有对象共享。

  37、C++试图让用户定义的类型尽可能与标准类型类似,因此可以在类中声明对象、指向对象的指针和对象数组。可以按值传递对象、将对象作为函数返回值、将一个对象赋给同类型的另一个对象。