第10章 对象和类
<c++ primer plus>第六版
目录
10 对象和类
重要的OOP特性:
- 抽象
- 封装和数据隐藏
- 多态
- 继承
- 代码的可重用性
10.1 过程性编程和面向对象编程
10.2 抽象和类
10.2.1 类型是什么
10.2.2 c++中的类
#ifndef STOCK00_H_
#define STOCK00_H_
#include <string>
class Stock //类声明
{
private:
std::string company;
long shares;
double share_val;
double total_val;
void set_tot()
{
total_val = share * 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();
}; //最后有一个分号.
#endif
10.3 类的构造函数和析构函数
10.3.1 声明和定义构造函数
class Stock
{};
//构造函数原型
Stock(const string &co, long n=0, double pr=0.0);
//构造函数定义
Stock::Stock(const string &co, long n, double pr)
{
compary = co; //注意co是参数名, compary是成员名, 它们不能相同, 解决方法1) 成员名加m_前缀, 2) 成员名加_后缀.
...
}
10.3.2 使用构造函数
两种方法调用构造函数, 是等价的:
- 显式调用: Stock grament = Stock("Furry Mason", 50, 2.5);
- 隐式调用: Stock garment("Furry Mason", 50, 2.5); //这种方法更紧凑.
构造函数与new 一起使用
Sock *pstock = new Stock("Electroshock Games", 18, 19.0); //初化一个对象后, 将对象地址赋值给指针.
注意: 不能通过对象来调用构造函数.
10.3.3 默认构造函数
Stock fluffy_the_cat; //未提供显式初始值时, 使用默认构造函数
定义默认构造函数的方式有两种:
- 给已有构造函数的所有参数提供默认值.
- 通过函数重载来定义另一个构造函数.
10.3.4 析构函数
析构函数完成清理工作.
//析构函数原型
~Stock();
//析构函数定义
Stock::~Stock()
{
}
10.3.5 改进Stock类
头文件stock10.h
//头文件, 声明类, 类成员, 类方法原型
#ifndef STOCK10_H_
#define STOCK10_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(); //默认构造函数
Stock(const std::string &co, long n=0, double pr=0.0); //带参数的构造函数
~Stock(); //析构函数
void buy(long num, double price);
void sell(long num, double price);
void update(double price);
void show();
};
#endif
//实现文件, stock10.cpp
// 实现类方法
#include <iostream>
#include "stock10.h" //双引号表示在源文件所在目录搜索它
//实现 默认构造函数
Stock::Stock()
{
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 share cannot be negative; " << company << " shares set to 0.\n";
shares = 0;
}
else
{
shares = n;
}
share_val = pr;
set_tot();
}
Stock::~Stock()
{
std::cout << "Bye, " << company << std::endl;
}
void Stock::show()
{
using std::cout;
using std::endl;
using std::ios_base;
ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);
std::streamsize prec = cout.precision(3);
cout << "Company : " << company << endl;
cout << "Shares : " << shares << endl;
cout << "Share Price: $" << share_val << endl;
cout.precision(2);
cout << "Total Worth: $" << total_val << endl;
cout.setf(orig, ios_base::floatfield);
cout.precision(prec);
}
//客户文件
#include <iostream>
#include "stock10.h"
int main()
{
using std::cout;
cout << "Using constructors to create new objects\n";
Stock stock1("NanoSmart", 12, 20.0);
stock1.show();
return 0;
}
//run文件
g++ stock10.cpp usestock.cpp -o usestock.exe
usestock.exe
注意: 如下两条语句有根本性差别,
第一条语句是初始化, 创建有指定值的对象, 这种效率更高.
Stock stock2 = Stock("Boffo Object", 2, 2.0);
第二条语句是赋值, 相当于创建一个临时对象然后赋值给stock1
stock1 = Stock("Nifty Foods", 10, 50.0);
c++11列表初始化
//使用构造函数 Stock::Stock(const std::string & co, long n=0, double pr=0.0)
Stock hot_tip = {"Derivatives Plus", 100, 45.0};
//使用构造函数 同上, 区别是后两个参数使用默认值.
Stock jock {"Sport Age Storage, Inc"};
//使用默认构造函数.
Stock temp {};
const成员函数
如果一个对象被声明为常对象, 则它只能调用常成员函数(不能修改类成员的函数)
常成员函数声明: void show() const; //注意const在后面
常成员函数定义: void Stock::show() const {};//注意const在后面
常成员函数调用: const Stock land = Stock("XX"); land.show();
10.4 this指针
this是一个指针, 指向调用当前成员函数的对象.
10.5 对象数组
Stock mystuff [4]; //创建一个数组, 包含4个Stock对象
Stock stocks[4] = {
Stock("0", 0, 0.0),
Stock("1", 1, 1.0),
Stock("2", 2, 2.0),
Stock("3", 3, 3.0),
Stock()
};
this->member
10.6 类作用域
前面提到的作用域:
全局作用域->文件作用域
局部作用域->代码块作用域
在类中定义的名称(类变量和类方法)的作用域为整个类. 在类外不可见.
调用类的函数只能通过对象.
使类成员名时, 根据上下文有三种方法:
1). 直接成员运算符(.)
2). 间接成员运算符(->)
3). 域解析运算符(:😃
10.6.1 作用域为类的常量
c++在类中定义常量的方式: 1) 使用枚举, 2)使用关键字static.
class Bakery
{
private:
static const int Months = 12; //类常量, 不存储在对象中.
double costs[Months];
}