首页 > 编程语言 >C++ Primer 学习笔记——第七章

C++ Primer 学习笔记——第七章

时间:2023-07-08 11:01:40浏览次数:42  
标签:const 函数 成员 定义 C++ 第七章 Primer data 构造函数

第七章 类

前言

基本数据类型有时候并不能解决某些特定问题,而通过自定义的类就可以通过理解问题概念,使得程序更加容易编写、调试和修改。

类的基本思想是数据抽象(data abstraction)和封装(encapsulation)。 数据抽象是一种依赖于接口(interface)和实现
(implementation)分离的编程(以及设计)技术。类的接口包括用户所能执行的操作;类的实现则包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。

可以说,封装实现了类的接口和实现的分离。封装后的类隐藏类它的实现细节。

介绍:

  • 定义抽象数据类型
  • 访问控制与封装
  • 类其他特性及作用域
  • 构造函数
  • 类静态成员

7.1 定义抽象数据类型

设计Sales_data类

其类接口包括:

  • 一个isbn成员函数,用于返回对象的ISBN编号
  • 一个combine成员函数,用于将一个Sales_data对象加到另一个对象上
  • 一个add函数,执行两个Sales_data对象的加法
  • 一个read函数,将数据从istream中读入到Sales_data对象中
  • 一个print函数,将Sales_data对象的值输出到ostream

开发

优秀的类设计者除了充分了解并实现用户的需求,还应该密切关注哪些有可能使用该类的程序员的需求。

一个设计良好的类,既要有易于使用的接口,也必须具备高效的实现过程。

注意

定义在类内部的函数是隐式的inline函数

定义改进的Sales_data类

定义成员函数

所有类成员必须在类内部声明,但是可以自由选择在类内或类外定义。

this使用

当我们调用成员函数时,实际上是某个对象调用它。例如:

/* 某个成员函数 */
std::string isbn() const { return bookNo; }

当我们调用isbn成员函数时,返回的bookNo数据成员,那么其隐式的返回的应该是total.bookNo(假设该函数的对象为total)。

成员函数通过一个名为this的额外隐式参数来访问调用它的那个对象。当我们调用一个成员函数时,用请求该函数的对象地址初始化this。例如:

/* 如果调用 */
total.isbn();
/* 编译器将会把total的地址传递给isbn的隐式形参this,等价于下面这个伪代码 */
Sales_data::isbn(&total);

注意

在成员函数内部,我们可以直接使用调用该函数的对象的成员,而无须通过成员访问运算符,因为this所指的正是这个对象。任何对类成员的直接访问都被看作this的隐式引用。

因为this的目的总是指向“这个”对象,所以this是一个常量指针。

引入const成员函数

在成员函数中,存在这种写法:

std::string isbn() const {return bookNo};

其中,const关键字作用于修改隐式this指针的类型。

在默认情况下,this的类型是指向类类型非常量版本的常量指针。对使用这种const方式的函数成为常量成员函数(const member function)。

我们可以将上述写法想象成:

std::string Sales_data::isbn(const Sales_data * const this){
    return this->bookNo;
}

类作用域和成员函数

类本身就是一个作用域,类的成员函数的定义嵌套在类的作用域之内

如果在类的外部定义成员函数,其定义必须与它的声明匹配,同时外部定义的成员的名字必须包含它所属的类名。

定义一个返回this对象的函数

定义类相关的非成员函数

类作者常常需要定义一些辅助函数,例如:add、read、print等等。这些辅助函数从概念上讲属于是类的接口的一部分,但是实际上其并不属于类。虽然实际上不属于类,但是概念上属于,所以一般将这些非成员函数写在同一个头文件中。

构造函数

构造函数(constructor)用于初始化类对象的数据成员,无论何时只要类被创建,就会执行构造函数。

构造函数名字与类名相同,与其他函数不同的是,构造函数没有返回类型;同时类可以包含多个构造函数,但是与重载函数不同的是,构造函数之间必须在参数列表或者参数类型上有所区别;同时构造函数不能被声明为const。

当我们没有显式声明并定义构造函数,那么类将会通过一个默认构造函数(default constructor)来控制默认初始化过程。编译器创建的构造函数同时又被称为合成的默认构造函数(synthesized default constructor)。但是合成的默认构造函数仅适合非常简单的类,对于一个普通的类,必须定义一个它自己的默认构造函数,因为:

  1. 编译器只有在类不包含任何构造函数的情况下才会替我们生成一个默认的构造函数。
  2. 含有内置类型或者复合类型成员的类在类的内部初始化时采用默认初始化很有可能其初始化值为未定义的。
  3. 有些时候编译器并不能为某些类合成默认的构造函数。

这里,使用一个示例进行分析:

SalesData()=default;        /* 默认构造函数,希望这个函数的作用等同于合成默认构造函数 */
SalesData(const std::string &str):_bookNo(str){}
SalesData(const std::string &str,unsigned number,double price):_bookNo(str),_units_sold(number),_revenue(price*number){}
SalesData(std::istream &);

=default,在C++标准中,使用SalesData()=default;方式要求编译器生成构造函数。该定义既可以在声明处,也可以在类外部。与其他函数一致,如果在类内部,则默认为内联方式,如果在类外部,默认不使用内联方式。

构造函数初始值列表

首先我们可以看看后两个定义的构造函数,在冒号和大括号之间存在的部分成为构造函数初始值列表(constructor initialize list)。其负责为新创建的对象的一个或者几个数据成员赋初值。

标签:const,函数,成员,定义,C++,第七章,Primer,data,构造函数
From: https://www.cnblogs.com/aaroncoding/p/17536713.html

相关文章

  • c++ 科幻版 沙漠神殿2
    #include<iostream>#include"minecraft.h"#include<string>usingnamespacestd;TxMinecraftmc;intx,y,z;boolcon;boollianjie(){ returncon=mc.ConnectMinecraft("mc.makeblock.net.cn","a9d44e758f6e4cf8b2da26241......
  • 请使用C++计算出2^2023与3^2023的和
    易知,这个和的数字是非常大的,大到longlong都装不下,这个时候如果使用longlong是无法进行运算的。欸!这会高精度算法(即大数运算)就开始发光发热了。以下是我看资料总结的一些歪瓜裂枣。对于一位高精度数字,用整数数组存储,数组每一个元素对应一位十进制数,由其下标顺序指明位序号......
  • c++沙漠神殿
    #include<iostream>#include"minecraft.h"#include<string>usingnamespacestd;TxMinecraftmc;intx=0,y=0,z=0;intmain(intargc,char**argv){boolcon=mc.ConnectMinecraft("zk.makeblock.net.cn","a9d44e758f6e4cf8b......
  • C++黑马程序员——P193-196. string容器 字符串比较,字符存取,字符串插入和删除,子串
    P193.string容器——字符串比较P194....——字符存取P195....——字符串插入和删除P196....——子串获取P193.字符串比较 ——————————————————————————————————————————————————————————1//字符......
  • C++黑马程序员——P189-192. string容器 构造函数,赋值,拼接,查找和替换
    P189.string容器——构造函数P190....——赋值操作P191....——字符串拼接P192....——字符串查找和替换P189.构造函数———————————————————————————————————————————————————————————————......
  • C++ 设计模式之建造者模式
    设计模式之建造者模式建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。其UML图如下:简单理解就是Builder中定义了创建Product各个部分的接口。ConcreteBuilder中具体实现了创建Product中的各个部分的接口,就是具体的建造者。Director......
  • C++设计模式之观察者模式
    设计模式之观察者模式观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。其UML图如下: 在ConcretSubject内部有一个Observer的列表,当Subject的状态发生改变时,会通知列表内......
  • C++ 设计模式之抽象工厂模式
    设计模式之抽象工厂模式抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。其UML图如下: 结合上图我们来理解一下抽象工厂模式的定义。提供一个创建一些列相关或相互依赖对象的接口,而无需指定它们具体的类。在上图中一系列相互依赖或相关......
  • C++ 设计模式之模板方法模式
    设计模式之模板方法模式模板方法模式,定义一个操作中的算法的股价,而将一些步骤延迟到了子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。说白了就是有一个算法有很多部分,这个算法在基类中已经定义好了。而算法中的各个部分都写成各个成员函......
  • C++ 设计模式之备忘录模式
    设计模式之备忘录模式备忘录,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。该模式很好理解,其UML图如下:在Originator中提供了创建Memento的接口,具体要保存什么样的内容,则根据需求来定。而Caretake......