一、问题引入
区分面向过程编程和面向对象编程的最大的特性就是 类
,类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组合成一个整洁的包。
那么如何声明类、定义类、调用类?
以 C++ Primer Plus:中文版 (第六版) 的股票类举例说明。
二、解决过程
2-1 类抽象
股票类的抽象化
-
获得股票
-
增持股票
-
减持股票
-
更新股票价格
-
显示所持股票的信息
股票的数据类型抽象化
-
发行股票公司名称
-
所持股票的数量
-
股票的单价
-
股票总值
2-2 类的代码实现
1️⃣ stock.h
#ifndef __STOCK_H__
#define __STOCK_H__
#include <string>
// 类的声明
class Stock {
public:
Stock(); // default constructor
Stock(const std::string & co, long n = 0, double pr = 0.0); // constructor prototype with some default arguments
~Stock(); // noisy destructor
void get_stock(const std::string & co, long n, double pr); // 获得股票
void add_stock(long num, double price); // 增持股票
void sell_stock(long num, double price); // 减持股票
void update_price(double price); // 更新股票价格
void show(); // 显示所持股票的信息
private:
std::string company; // 发行股票公司名称
long shares; // 所持股票的数量
double share_val; // 股票的单价
double total_val; // 股票总值
void set_total() {total_val = shares * share_val;};
};
#endif
2️⃣ stock.cpp
#include "stock.h"
#include <iostream>
// default constructor
Stock::Stock()
{
company = "no name";
shares = 0;
share_val = 0.0;
total_val = 0.0;
}
// class destructor
Stock::~Stock() // verbose class destructor
{
}
// 构造函数的参数表示的不是类成员,而是赋给类成员的值。因此,参数名不能与类成员相同,否则出现同名混乱
Stock::Stock(const std::string & co, long n, double pr)
{
company = co;
if(n < 0)
{
std::cerr << "Number of shares can't be negative; "
<< company << " shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_total();
}
/* other methods */
void Stock::get_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;
}
else
shares = n;
share_val = pr;
set_total();
}
void Stock::add_stock(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_total();
}
}
void Stock::sell_stock(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_total();
}
}
void Stock::update_price(double price)
{
share_val = price;
set_total();
}
void Stock::show()
{
using std::cout;
using std::endl;
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 << "Stock Information:" << endl;
cout << "Company company: " << company << endl;
cout << "Number of Stocks: " << shares << endl;
cout << "Price per Stock: $" << share_val<< endl;
// set format to #.##
cout.precision(2);
cout << "Total Value: $" << total_val<< endl;
// restore original format
cout.setf(orig, ios_base::floatfield);
cout.precision(prec);
}
3️⃣ stock_call.cpp
#include <iostream>
#include "..\inc\stock.h"
int main(void)
{
Stock fluffy_the_cat("NanoSmart", 0, 0.0);
fluffy_the_cat.get_stock("NanoSmart", 20, 12.50);
fluffy_the_cat.show();
std::cout << '\n';
fluffy_the_cat.add_stock(15, 18.125);
fluffy_the_cat.show();
std::cout << '\n';
fluffy_the_cat.sell_stock(400, 20);
fluffy_the_cat.show();
std::cout << '\n';
fluffy_the_cat.add_stock(300000, 40.125);
fluffy_the_cat.show();
std::cout << '\n';
fluffy_the_cat.sell_stock(300000, 0.125);
fluffy_the_cat.show();
return 0;
}
运行结果
2-3 类的构造函数和析构函数
构造函数:类的特殊成员函数,专门用于构造新对象、将值赋给类的数据成员
-
构造函数的名称和类名称相同
-
构造函数没有返回值
-
一个类至少有一个构造函数,但一般会有多个构造函数:默认构造函数、拷贝构造函数、赋值构造函数
/* 默认构造函数没有参数 */
Stock(); // default constructor
/* 用户定义构造函数可以有参数或有部分参数 */
Stock(const std::string & co, long n = 0, double pr = 0.0); // constructor prototype with some default arguments
析构函数:类的特殊成员函数,专门用于销毁过期对象的内存
-
构造函数的名称和类名称相同,但需要在名字前添加符号:
~
-
一个类有且只有析构函数
-
析构函数无参数,也无返回值
~Stock(); // noisy destructor
2-4 同类的的比较
若用户希望根据类的某一个值进行比较,返回值较大的类,该如何实现。
在类的公共接口新增方法即可,此处以股票类举例:
stock.h
// 类的声明
class Stock {
public:
// 此处省略重复信息
const Stock & top_val(const Stock & s) const; // 比较两只股票总值,得到总值较大的一只
private:
// 此处省略重复信息
};
stock.cpp
// 此处省略重复信息
const Stock & Stock::top_val(const Stock & s) const
{
if (s.total_val > total_val)
return s;
else
return *this;
}
main()
#include <iostream>
#include "..\inc\stock.h"
int main(void)
{
Stock google, intel;
google.get_stock("google", 100, 120);
google.show();
std::cout << '\n';
intel.get_stock("intel", 100, 150);
intel.show();
std::cout << '\n';
Stock top = google.top_val(intel);
top.show();
std::cout << '\n';
return 0;
}
三、反思总结
一般来说,类规范由两部分组成。
-
类声明:以数据成员的方式描述数据部分,以成员函数(即方法)的方式描述公有接口
-
类方法定义:描述如何实现类成员函数
关于函数:const Stock & top_val(const Stock & s) const;
的理解
第一个 const
:由于该函数返回了两个const 对象之一的引用,因此返回类型也应为const应用
第二个 const
:该函数不会修改被显示地访问的对象(即 s)
第三个 const
:该函数不会修改被隐式地访问的对象
this
指针指向用来调用成员函数的对象(this 被作为隐藏参数传递给方法)文章来源:https://www.toymoban.com/news/detail-412333.html
四、参考引用
C++ Primer Plus:中文版 (第六版)文章来源地址https://www.toymoban.com/news/detail-412333.html
到了这里,关于C++的对象和类的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!