第一步:
#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 = 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();
};
#endif
第二步:
#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 cant be negative; "
<< company << "shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
void Stock::buy(long num, double price)
{
if (num < 0)
{
std::cout << "Number of shares purchaseed 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';
*/
using std::cout;
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
<< "Shares: " << shares << "\n";
cout << " Share Price: $" << share_val;
cout.precision(2);
cout << " Total Worth: $" << total_val << "\n";
cout.setf(orig, ios_base::floatfield);
cout.precision(prec);
}
第三步:
#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(30000, 40.125);
fluffy_the_cat.show();
fluffy_the_cat.sell(30000, 0.125);
fluffy_the_cat.show();
while(1);
return 0;
}
小结:
指定类设计的第一步是提供类声明。类声明类似结构声明,可以包括数据成员和函数成员。声明有私有部分,在其中声明的成员只能通过成员函数进行访问;声明还具有
公有部分,在其中声明的成员可被使用类对象的程序直接访问。通常,数据成员被放在私有部分中,成员函数被放在公有部分中,因此典型类声明的格式如下:
class className
{
private:
data member declarations
public:
member function prototypes
}
公有部分的内容构成了设计的抽象部分——公有接口。将数据封装到私有部分中可以保护数据的完整性,这被称为数据隐藏。因此,C++通过类使得实现抽象、数据隐藏
和封装等OOP特性很不容易。
指定类设计的第二步是实现类成员函数。可以在类声明中提供完整的函数定义,而不是函数原型,但是通常的做法是单独提供函数定义(除非函数很小)。在这种情况下,需要使用作用域解析运算符来指出成员函数属于哪个类。例如,假设Bozo有一个名为Retort()的成员函数,该函数返回cha指针,则其函数头如下所示:
char * Bozo::Retort()
换句话来说,Retort()不仅是一个char*类型的函数,而是一个属于Bozo类的char*函数。该函数的全名(或限定名)为Bozo::Retort()。而名称Retort()是限定名的缩写,只能在某些特定的环境中使用,如类方法的代码中。
另一种描述这种情况的方式是,名称Retort的作用域为整个类,因此在类声明和类方法之外使用该名称时,需要使用作用域解析运算符进行限定。
要创建对象(类的实例),只需将类名视为类型名即可:
Bozo bozetta;
这样做是可行的,因为类是用户定义的类型。
类成员函数(方法)可通过类对象来调用。为此,需要使用成员运算符句点:
cout << bozetta.Retort();
这将调用Retort()成员函数,每当其中的代码引用某个数据成员时,该函数都将使用bozetta对象中相应成员的值。