C++ Primer Plus第十章摘要

2020年

 

第十章  对象和类

 

本章内容:

过程性编程和面向对象编程

类概念

如何定义和实现类

公有类和私有类访问

类的数据成员

类方法(类的函数成员)

创建和使用类对象

类的构造函数和析构函数

const成员函数

this指针

创建函数数组

类作用域

抽象数据类型

 

1.最重要的oop特性;

   抽象

   封装和数据隐藏

   多态

   继承

   代码的可重用性

 

2.类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组合成一个简洁的包。

 

3.类规范的组成:

   类声明:以数据成员的方式描述数据部分,以成员函数的方式描述公有接口。

   类方法定义:描述如何实现类成员函数。

 

4.接口让程序员能够编写与类对象交互的代码,从而让程序能够使用类对象。

 

5.通常,C++程序员将接口(类定义)放在头文件中,并将实现(类方法的代码)放在源代码文件中。

 

6.为帮助识别类,有一种常见但不通用的约定——将类名首字母大写。

 

7.公有成员函数是程序和对象的私有成员之间的桥梁,提供了对象和程序之间的接口。

防止程序直接访问数据被称为数据隐藏。

   由于隐藏数据是oop主要的目标之一,因此数据项通常放在私有部分。组成类接口的成员函数放在公有部分。

   也可以把成员函数放在私有部分中。不能直接从程序中调用这种函数,但公有方法却可以使用它们。通常,程序员使用私有成员函数来处理不属于公有接口的实现细节。

 

8.不必在类声明中使用关键字private,因为这是类对象的默认访问控制。

 

9.类成员函数具有两个特殊特征

   1.定义成员函数时,使用作用域解析运算符(: :)来标识函数所属的类;

   2.类方法可以访问类的private组件。

  

10.同类的其他成员函数不必使用作用域解析运算符,就可以使用update( )方法,这是因为它们属于同一个类,因此update( )是可见的。

 

11.其定义位于类声明中的函数都将自动成为内联函数。

    如果愿意也可以在类声明之外定义成员函数,并使其成为内联函数,只需在类实现部分中定义函数时使用inline限定符即可。

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

 

12.所创建的每一个新对象都有自己的存储空间,用于存储其内部变量和类成员;

     但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。

     我倾向于将函数看作一种数据处理方式,对象在变,处理的方式不会变。

 

13.要创建类对象,可以声明类变量,也可以使用new为类对象分配存储空间。可以将对象作为函数的参数和返回值,也可以将一个对象赋给另外一个。

 

14.类的构造函数

    C++的目标之一是让使用类对象就像使用标准类型一样,然而,常规的初始化语法不适用于类型.

    程序只能通过成员函数来访问数据成员,因此需要设计合适的成员函数,才能成功地将对象初始化。粗暴的使数据成为公有的违背了类的一个主要初衷:数据隐藏。

    构造函数的原型和函数头有一个有趣的特征——虽然没有返回值,但没有被声明为void类型。实际上,构造函数没有声明类型。

    不熟悉构造函数的您会试图将类成员名称用作构造函数的参数名。

    构造函数的参数表示的不是类成员,而是赋给类成员的值。因此参数名不能与类成员相同,否则最终的代码会造成混乱。

    避免混乱的最常见做法是数据成员名加上m_前缀或使用后缀_;

   

     C++提供了两种使用构造函数来初始化对象的方式

     1.显式地调用构造函数

        Stock food=Stock("World Cabbage",250,1.25);

        C++标准允许编译器使用两种方式来执行语法。

        一种和隐式调用语法完全相同,一种允许构造函数来创建一个临时对象,然后将该临时对象复制到Stock2中,并丢弃它。如果编译器使用的是这种方式,则将为临时对象调用析构函数。

 

     2.隐式地调用构造函数,格式更加紧凑,是一种模拟标准类型的方法

       Stock garment("Furry Mason",50,2.5);

    

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

     当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数。为类定义了构造函数后,程序员就必须为它提供默认构造函数(default constructor)。如果提供了非默认构造函数,但没有提供默认构造函数,不提供初始值的初始化将出错。定义默认构造函数的方式有两种,一种是给已有构造函数的所有参数提供默认值,一种是通过函数重载来定义另一个构造函数——一个没有参数的构造函数。

       Stock(const string& co="Error",int n=0,double pr=0.0);

       Stock::Stock()

       {

             company="no name";

             shares=0;

             share_val=0.0;

             total_val=0.0;

        }
 

15.类的析构函数

     析构函数完成清理工作。

     析构函数也可以没有返回值和声明类型。与构造函数不同的是,析构函数没有参数,因此析构函数的原型是固定的。

      如果创建的是自动存储类对象,其析构函数将在程序执行完代码块时自动被调用。如果对象是通过new创建的,则它将驻留在栈内存或自由存储区中,当使用delete来释放内存时,析构函数将自动被调用。

      如果程序员没有提供析构函数,编译器将隐式的声明一个默认析构函数。

     

16.构造函数不仅仅可用于初始化新对象。

     stock1=Stock("Nifty Foods",10,50.0);

     这句话是将新值赋给stock1。通过让构造程序创建一个新的、临时的对象,然后将其内容复制给stock1来实现的。随后程序调用析构函数,已删除该临时对象。

 

17.函数main()结束时,其局部变量(stock1和stock2)将消失。由于这种自动变量被放在栈中,因此最后创建的对象最先被删除。

 

18.即可以通过初始化,也可以通过赋值来设置对象的值,则应采用初始化方式。通常这种方式的效率更高。

 

19.C++11中,可以将列表初始化语法适用于类,只要提供与某个构造函数的参数列表匹配的内容。

 

20.const成员函数

     声明: void show( ) const;

     定义: void stock::show( ) const;

     只要类方法不修改调用对象,就将其声明为const.

 

21.动态类的创建:

     Bozo *pc = new Bozo {"Popo","Le Peu"};

     如果构造函数使用了new,则必须提供使用delete的析构函数。

 

22.this指针

     通常使用内联const代码来用最直接的方式返回存储的数据。

   

     有的时候方法可能涉及到两个对象,在这种情况下需要使用C++的this指针。

     如何将两个要比较的对象提供给成员函数:使函数隐式的访问一个对象,显式的访问另一个对象,并返回其中一个对象的引用。

     const Stock& topval(const Stock&s)const;

     {

            if(s.total.val>total_val)   //这里的total_val其实是this->total_val的缩写

               return s;

            else

               return *this

      }

     top=stock1.topval(stock2);

     返回类型为引用意味着返回的是调用对象本身,而不是其副本。

 

23.对象数组

     声明对象数组的方法与声明标准类型数组相同。

     可以用构造函数来初始化数组元素,在这种情况下,必须为每个元素调用构造函数。

     Stock stocks[4]={
            Stock("NanoSmart",12.5,20),

            Stock("Boffo Object",200.2.0),

            Stock("Monolithic Obelisks",130,3,25),

            Stock("Fleep Enterprises",60,6.5)

            };

     如果声明只初始化数组的部分元素,余下的元素将使用默认构造函数进行初始化。初始化对象数组的方案是,首先使用默认构造函数创建数组元素,然后花括号中的构造函数将创建临时对象,然后将临时对象的内容复制到相应的元素中。

 

24.类定义域

     作用域为类的常量的声明方法:

     1.使用枚举变量

    class Bakery

     {

     private:

           enum{Months=12};

           double costs[Months];

            . . .

      }

     2.使用关键字static

    class Bakery

    {

    private:

          static const int Months=12;

          double cost[Months];

     }
 

25.抽象数据类型

     栈容器

     

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我怎么对这么多事情都感兴趣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值