C++菜鸟学习笔记系列(20)——定义抽象类型

简介: C++菜鸟学习笔记系列(20)——定义抽象类型

C++菜鸟学习笔记系列(20)

本期主题:定义抽象类型

我们曾经在C++菜鸟学习笔记系列(5)中介绍了一些关于自定义数据类型的知识,在上一篇博客中我们定义的Sale_data类比较简单,只是在struct关键字中定义了一些基本数据类型组成一个结构体,对于这个Sale_data类允许类的用户直接访问它的数据成员,并且要求由用户编写操作。与之相反的我们在这一篇博客中主要是介绍抽象数据类型。


我们再来了解一下类:

类的基本思想是数据抽象和封装。数据抽象是一种依赖于接口和实现分离的编程技术。


(1)类的接口包括用户所能执行的操作;

(2)类的实现规则包括类的数据成员、负责接口实现的函数体以及定义类所需要的各种私有函数。


封装实现了类的接口和实现的分离。封装后的类隐藏了它的实现细节,也就是说类的用户只能使用接口而无法访问实现部分。


类要想实现数据抽象和封装需要定义一个抽象数据类型,在抽象数据类型中,有类的设计者负责考虑类的实现过程,而类的使用者(用户)负责抽象地思考类型做了什么,而无需了解类型的工作细节。


程序员们通常把使用其程序的人称为用户。类似的类的设计者也是为其用户设计并实现一个类型的人,而类的使用者则是用户。


在本篇博客中我们来通过分别作为设计者和用户两个不同的角色来理解抽象类的定义。


我们先来思考一下我们定义的Sale_data类要具体实现什么功能,包含什么操作:


一个isbn成员函数,用于返回对象的ISBN编号。

一个combine成员函数,用于将一个Sale_data对象加到另一个对象上。

一个名为add的函数,执行两个Sale_data对象的加法。

一个read函数,将数据从istream读入到Sale_data对象中。

一个print函数,将Sale_data对象的值输出到ostream。

最近事情比较多,不想写了,直接上代码吧。

sale_data.h头文件

#include <iostream>
#include <string>
struct sale_data
{
  std::string isbn() 
    const 
  {
    return bookno;
  }
  sale_data& combine(const sale_data&);
  double avg_price() const
{
  if (units_sold != 0)
  {
    return revenue / units_sold;
  }
  else
  {
    return 0;
  }
}
  std::string bookno;
  int units_sold;
  double revenue;
};
//double sale_data::avg_price() 
sale_data add (const sale_data& sd1, const sale_data& sd2);
std::ostream &print (std::ostream &out, const sale_data &sd);
std::istream &read (std::istream &in, sale_data &sd);

main.cpp文件

/*
author:wxc_1998
date:2018/11/16
*/
#include <iostream>
#include "sale_data.h"
using namespace std;
void main()
{
  sale_data total;
  if (read(cin,total))
  {
    sale_data trans;
    while (read(cin,trans))
    {
      if (total.bookno == trans.bookno)
      {
        total.combine(trans);
      }
      else
      {
        print (cout, total);
        cout << endl; 
        total = trans;
      }
    }
    print(cout, total);
    cout << endl;
  }
  else
  {
    cerr << "No data?" << endl;
  }
  cout << "please press any key to continue!" << endl;
  cin.clear();
  cin.sync();
  cin.get();
}

combine.cpp文件

#include <iostream>
#include "sale_data.h"
sale_data& sale_data::combine(const sale_data& sd)
{
  units_sold += sd.units_sold;
  revenue += sd.revenue;
  return *this;
}

add.cpp文件

#include <iostream>
#include "sale_data.h"
sale_data add (const sale_data& sd1, const sale_data& sd2)
{
  sale_data sum = sd1;
  sum.combine(sd2);
  return sum;
}

read.cpp文件

#include <iostream>
#include "sale_data.h"
using namespace std;
istream &read(istream &in, sale_data &sd)
{
  double price = 0;
  in >> sd.bookno >> sd.units_sold >> price;
  sd.revenue = sd.units_sold * price;
  return in;
}

print.cpp文件

#include <iostream>
#include "sale_data.h"
using namespace std;
ostream &print(ostream &out, const sale_data &sd)
{
  out << sd.bookno << "  " << sd.units_sold << "  " << sd.revenue
    << "  " << sd.avg_price(); ;
  return out;
}
目录
相关文章
|
4月前
|
存储 算法 安全
c++模板进阶操作——非类型模板参数、模板的特化以及模板的分离编译
在 C++ 中,仿函数(Functor)是指重载了函数调用运算符()的对象。仿函数可以像普通函数一样被调用,但它们实际上是对象,可以携带状态并具有更多功能。与普通函数相比,仿函数具有更强的灵活性和可扩展性。仿函数通常通过定义一个包含operator()的类来实现。public:// 重载函数调用运算符Add add;// 创建 Add 类的对象// 使用仿函数return 0;
140 0
|
7月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
403 6
|
11月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
569 4
|
存储 编译器 程序员
C++类型参数化
【10月更文挑战第1天】在 C++ 中,模板是实现类型参数化的主要工具,用于编写能处理多种数据类型的代码。模板分为函数模板和类模板。函数模板以 `template` 关键字定义,允许使用任意类型参数 `T`,并在调用时自动推导具体类型。类模板则定义泛型类,如动态数组,可在实例化时指定具体类型。模板还支持特化,为特定类型提供定制实现。模板在编译时实例化,需放置在头文件中以确保编译器可见。
135 11
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
170 2
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
137 1
|
安全 C语言 C++
C++学习笔记
C++学习笔记
HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具
HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具
|
安全 程序员 C语言
C++(四)类型强转
本文详细介绍了C++中的四种类型强制转换:`static_cast`、`reinterpret_cast`、`const_cast`和`dynamic_cast`。每种转换都有其特定用途和适用场景,如`static_cast`用于相关类型间的显式转换,`reinterpret_cast`用于低层内存布局操作,`const_cast`用于添加或移除`const`限定符,而`dynamic_cast`则用于运行时的类型检查和转换。通过具体示例展示了如何正确使用这四种转换操作符,帮助开发者更好地理解和掌握C++中的类型转换机制。
|
C++
使用 QML 类型系统注册 C++ 类型
使用 QML 类型系统注册 C++ 类型
458 0