以C++ Primer Plus为参考书籍,自身归纳知识点,加深记忆。

对象和类

  • 过程性编程与面向对象编程
  • 对象和类
      • 类声明
      • 实现类成员函数
      • 方法与对象
  • 类的构造函数与析构函数
    • 声明和定义构造函数
    • 使用构造函数
    • 默认构造函数(defult constructor)
    • 析构函数(destructor)
    • const成员函数
    • C++11列表初始化
  • this指针
  • 对象数组

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

过程性编程:首先考虑要遵循的步骤,然后考虑如何表示这些数据
面向对象编程:首先从用户的角度考虑对象,描述对象所需的数据以及描述用户与数据交互所需的操作,完成对接口的描述后,需要确定如何实现接口与数据储存,最后使用新的设计方案创建出程序。

对象和类

类是一种将抽象转化为用户定义类型的C++工具,将数据表示和数据操作的方法组合成一个整合包。
一般来说,类规范由两个部分组成:
①类声明:以数据成员的方式描述数据部分,以成员函数(方法)的方式描述公有接口
②类方法定义:描述如何实现类成员函数
简单地说,类声明提供蓝图,类方法定义提供细节。

类声明

//类声明
//stock00.h
#include<iostream>class Stock//class不同于模板参数的typename,不能代替,Stock为新类型名
{private://私有部分,一般是数据通项std::string company;long shares;double share_val;double total_val;void set_tot(){total_val = shares*share_val;}
public://公有部分,一般是组成类成员函数声明void acquire(const std::string &co,long n, double pr);void buy(long num,double price);void sell(long num,double price);void update(double price);void show();
};

使用类对象的程序都可以使用公有部分,但只能通过公有成员函数访问对象的私有成员。将实现细节放在一起并将它们与抽象分开被称为封装。

实现类成员函数

成员函数的定义与常规函数定义非常相似,它们有函数头和函数体,也可以有返回类型和参数,但还有两个特殊的特征:
①定义成员函数,使用作用域解析符::来表示函数所属的类
②类方法可以访问类的private组件

void Stock::update(double price)//update是Stock类的成员函数,还可以将另一个类的成员函数声明为update
//标识符update()具有类作用域
// stock00.cpp -- implementing the Stock class
// version 00
#include <iostream>
#include "stock00.h"void Stock::acquire(const std::string & co, long n, double pr)
{company = co;if (n < 0){std::cout << "Number of shares can't be negative; "<< company << " shares set to 0.\n";shares = 0;}elseshares = n;share_val = pr;set_tot();
}void Stock::buy(long num, double price)
{if (num < 0){std::cout << "Number of shares purchased can't be negative. "<< "Transaction is aborted.\n";}else{shares += num;share_val = price;set_tot();}
}void Stock::sell(long num, double price)
{using std::cout;if (num < 0){cout << "Number of shares sold can't be negative. "<< "Transaction is aborted.\n";}else if (num > shares){cout << "You can't sell more than you have! "<< "Transaction is aborted.\n";}else{shares -= num;share_val = price;set_tot();}
}void Stock::update(double price)
{share_val = price;set_tot();
}void Stock::show()
{std::cout << "Company: " << company<< "  Shares: " << shares << '\n'<< "  Share Price: $" << share_val<< "  Total Worth: $" << total_val << '\n';
}

方法与对象

创建对象:

Stock kate,joe;

使用成员函数:

kate.show();
joe.show();

创建的每一个对象都有自己的存储空间,用于存储其内部的变量和类成员,但同一个类的所有对象共享同一组类的方法,即每种方法只有一个副本,在OOP中,调用成员函数被称为发送消息,因此将同样的消息发送给两个不同的对象将调用同一个方法,但该方法被用于两个不同的对象

// usestok0.cpp -- the client program
// compile with stock.cpp
#include <iostream>
#include "stock00.h"int main()
{Stock fluffy_the_cat;fluffy_the_cat.acquire("NanoSmart", 20, 12.50);fluffy_the_cat.show();fluffy_the_cat.buy(15, 18.125);fluffy_the_cat.show();fluffy_the_cat.sell(400, 20.00);fluffy_the_cat.show();fluffy_the_cat.buy(300000,40.125);fluffy_the_cat.show();fluffy_the_cat.sell(300000,0.125);fluffy_the_cat.show();// std::cin.get();return 0;
}

类的构造函数与析构函数

声明和定义构造函数

Stock (const string &co,long n =0, double pr = 0.0);//没有返回类型,构造函数声明
//定义构造函数
Stock::Stock(const std::string & co, long n, double pr)
{company = co;if (n < 0){std::cout << "Number of shares can't be negative; "<< company << " shares set to 0.\n";shares = 0;}elseshares = n;share_val = pr;set_tot();
}

使用构造函数

构造函数初始化对象有两种方式:

Stock food = Stock("World Cabbage",250,2.5);//显示调用构造函数
Stock garmer("Furry Mason",50,1.25);//隐式调用构造函数
Stock *pstock = new Stock("Electroshock Games",18,20.5);//对象指针

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

默认构造函数(defult constructor)

默认构造函数实在未提供显示初始值时,用来创建对象的构造函数。如果没有提供任何构造函数,C++将自动提供默认构造函数,它是默认构造函数的隐式版本,不做任何工作。默认构造函数没有参数,因为没有声明中不包含值

定义默认构造函数的方式有两种:

Stock(const string &co="ERROR",int n=0,double pr=0);//给已有构造函数的所有参数提供默认值
Stock();//函数重载,一个没有任何参数的构造函数。
//只有能有一种默认构造函数,不要同时采用

析构函数(destructor)

用构造函数创建一个对象后,程序负责跟踪该对象,直到其过期为止。对象过期时,程序将自动调用一个特殊的成员函数完成清理工作。
和构造函数一样,析构函数的名称很特殊。在类名前加上~,没有返回值和声明类型,并且没有参数:

~Stock();

①如果创建的是静态存储类对象,析构函数将在程序结束时自动调用
②如果创建的是自动存储类对象,析构函数将在程序运行完代码块时自动被调用
③如果对象是通过new创建,析构函数将驻留在栈内存或者自由存储区中,当使用delete释放内存时,析构函数将会自动被调用
④程序创建临时对象来完成特定操作,在这种情况下,程序将结束该对象的使用时自动调用其析构函数。

// stock10.h ?Stock class declaration with constructors, destructor added
#ifndef STOCK1_H_
#define STOCK1_H_
#include <string>
class Stock
{private:std::string company;long shares;double share_val;double total_val;void set_tot() { total_val = shares * share_val; }
public:Stock();        // default constructorStock(const std::string & co, long n = 0, double pr = 0.0);~Stock();       // noisy destructorvoid buy(long num, double price);void sell(long num, double price);void update(double price);void show();
};#endif
// stock1.cpp ?Stock class implementation with constructors, destructor added
#include <iostream>
#include "stock10.h"// constructors (verbose versions)
Stock::Stock()        // default constructor
{std::cout << "Default constructor called\n";company = "no name";shares = 0;share_val = 0.0;total_val = 0.0;
}Stock::Stock(const std::string & co, long n, double pr)
{std::cout << "Constructor using " << co << " called\n";company = co;if (n < 0){std::cout << "Number of shares can't be negative; "<< company << " shares set to 0.\n";shares = 0;}elseshares = n;share_val = pr;set_tot();
}
// class destructor
Stock::~Stock()        // verbose class destructor
{std::cout << "Bye, " << company << "!\n";
}// other methods
void Stock::buy(long num, double price)
{if (num < 0){std::cout << "Number of shares purchased can't be negative. "<< "Transaction is aborted.\n";}else{shares += num;share_val = price;set_tot();}
}void Stock::sell(long num, double price)
{using std::cout;if (num < 0){cout << "Number of shares sold can't be negative. "<< "Transaction is aborted.\n";}else if (num > shares){cout << "You can't sell more than you have! "<< "Transaction is aborted.\n";}else{shares -= num;share_val = price;set_tot();}
}void Stock::update(double price)
{share_val = price;set_tot();
}void Stock::show()
{using std::cout;using std::ios_base;// set format to #.###ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield); std::streamsize prec = cout.precision(3);cout << "Company: " << company<< "  Shares: " << shares << '\n';cout << "  Share Price: $" << share_val;// set format to #.##cout.precision(2);cout << "  Total Worth: $" << total_val << '\n';// restore original formatcout.setf(orig, ios_base::floatfield);cout.precision(prec);
}
// usestok1.cpp -- using the Stock class
// compile with stock10.cpp
#include <iostream>
#include "stock10.h"int main()
{{using std::cout;cout << "Using constructors to create new objects\n";Stock stock1("NanoSmart", 12, 20.0);            // syntax 1stock1.show();Stock stock2 = Stock ("Boffo Objects", 2, 2.0); // syntax 2stock2.show();cout << "Assigning stock1 to stock2:\n";stock2 = stock1;//可以将一个对象赋给同类型的另一个对象cout << "Listing stock1 and stock2:\n";stock1.show();stock2.show();cout << "Using a constructor to reset an object\n";stock1 = Stock("Nifty Foods", 10, 50.0);    // temp objectcout << "Revised stock1:\n";stock1.show();cout << "Done\n";}// std::cin.get();return 0;
}

const成员函数

void show()const;//将const放在函数括号后面

C++11列表初始化

Stock hot = {"Dedwadd dfwf fw",110,23.2};
Stock dw {"sdded dad",121,2.1};//与构造函数匹配
Stock temp {};//与默认构造函数匹配

this指针

this指针指向用来调用成员函数的对象。

stock1.topval(stock2)//this设置为stock1的地址

每个成员函数包括构造函数和析构函数都有一个this指针,this指针指向调用对象,在函数括号后面使用const限定符将this限定为const,这样不能使用this修改对象的值。

对象数组

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

Stock mystuff[4];

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

Stock stocks[4] = {Stock("dqguydi dfwq",12.5,20),//也可以交叉使用默认构造函数Stock("dswd",12.2,21),Stock("dedes ded"12.6,78),Stock("dsve fgte"32.9,89)};

2020 我的C++的学习之路 第十章 对象和类相关推荐

  1. C++学习笔记-第4单元-对象和类(基础)

    C++学习笔记 文章目录 C++学习笔记 第4单元 对象和类(基础) 单元导读 4.1 用类创建对象 4.1.1 对象和类 4.1.2 创建对象并访问 4.2 对象拷贝.分离声明与实现 4.2.1 对 ...

  2. Python 学习笔记 系统模块 面对对象思想 类和对象 类中的方法与对象 构造函数和析构函数

    一.系统模块: UTC:国际标准时间, 格林尼治天文时间,UTC+8 时间戳:指定时间距离1970.1.1 00:00:00的秒数 time:时间 datetime:日期 calendar:万年历 o ...

  3. 2020 我的C++的学习之路 第九章 内存模型与名称空间

    以C++ Primer Plus为参考书籍,自身归纳知识点,加深记忆. 内存模型与名称空间 存储持续性 作用域与链接 自动存储持续性 静态持续变量 静态持续性.外部链接性 静态持续性.内部链接性 静态 ...

  4. 2020 我的C++的学习之路 第八章函数

    以C++ Primer Plus为参考书籍,自身归纳知识点,加深记忆. 第八章 函数探幽 1 内联函数 2 引用变量 2.1 创建引用变量 2.2 引用与函数参数 2.3 引用与结构 何时使用引用参数 ...

  5. 2020 我的C++的学习之路

    以C++ Primer Plus为参考书籍,自身归纳知识点,加深记忆. 第四章 复合类型 4.1 数组 数组(array)是一种数据格式,存储多个同类型的值.声明数组应指出数组中元素的类型,元素数量以 ...

  6. Qt 学习之路 :Qt 线程相关类

      希望上一章有关事件循环的内容还没有把你绕晕.本章将重新回到有关线程的相关内容上面来.在前面的章节我们了解了有关QThread类的简单使用.不过,Qt 提供的有关线程的类可不那么简单,否则的话我们也 ...

  7. 菜鸟的学习之路(13) —TreeSet类的排序

    一.TreeSet类解析: 1.TreeSet是依靠TreeMap实现的. 2.TreeSet中不能有重复的元素,而且是有序排列的. 3.自定义的类要想实现排序,实现Comparable接口,重写co ...

  8. 菜鸟的学习之路(12) —HashSet类详解

    一.HashSet类详解: HashSet类的底层是HaskMap实现的.存入HashSet的元素是有HashMap的key来保存的.而HashMap的值是一个Object对象. HashSet中是不 ...

  9. 菜鸟的学习之路(10) — LinkedList类

    一.认识LinkedList类: 实现的接口:Serializable,Cloneable,Iterable,Collection,Deque,List,Queue 父类:AbstractSequen ...

最新文章

  1. 独家 | 浅谈Python/Pandas中管道的用法
  2. 关于在WINDOWS XP 下运行的PIX模拟器
  3. 模拟浏览器自动化测试工具Selenium之六设置代理篇
  4. Android之应用APN、WIFI、GPS定位小例子
  5. php 模板替换,使用PHPWord对Word文件做模板替换
  6. WebCombo 客户端绑定数据
  7. python基础之01数据类型-变量-运算浅解
  8. 【每日SQL打卡】DAY 1丨部门工资最高的员工【难度中等】
  9. 求第k小的数(洛谷P1923题题解,Java/C++语言描述)
  10. python编程基础张勇答案_Python程序开发、编程基础阶段试题及答案
  11. 判断画布中有重复纪录
  12. python中tolist_python 列表,数组,矩阵两两转换tolist()的实例
  13. 2n皇后问题(dfs)
  14. 算法与数据结构实验题 4.1 伊姐姐数字 game
  15. cv2.cvtColor报错
  16. 应用Scratchbox构建基于CF卡的嵌入式Linux系统
  17. 使用内核模块添加系统调用
  18. 中国的开源之夏来了!
  19. matlab 中值滤波 medifit,基于多级中值滤波-提升小波技术的图像去噪
  20. 不同颜色蔬菜代表什么营养?

热门文章

  1. [ARM异常]-异常进入和异常退出时的arm core的硬件自动的行为
  2. 08-Measured Boot Driver (MBD)
  3. php reverseShell
  4. 设计模式C++实现(7)——外观模式、组合模式
  5. C. Woodcutters【贪心】
  6. 【PAT乙级】1019 数字黑洞 (20 分)
  7. raise IOError('The file is not exist!')
  8. linux之账号管理
  9. MySQL中的组合索引
  10. Spring boot的Bean使用JSR 303校验