类的基础
1.cpp中对象默认访问权限都是private的
2.私有成员只能通过公有函数访问使用
3.类方法名称需包含类名,为函数的限定名
在头文件中定义类,同时将公有方法原型声明(类似Java接口道理).
#ifndef STOCK00_H_
#define STOCK00_H_
#include<string>
//股票类
class Stock {
//私有部分
private:
//枚举类
enum class egg_old:int
{
Small, MediummLarge, Jumbo
};
//公司名
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);
//获得用户持有股票信息
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);
//比较大小
const Stock& topval(const Stock& s) const;
//查看
void show() const;
const Stock copyNew();
};
#endif // !STOCK00_H_
在同名源文件中实现公有函数定义.
#include<iostream>
#include"stock00.h"
//创建成员函数,成员函数可以直接访问类中私有部分成员
//默认构造器,如果没有编译器会自动实现
Stock::Stock() {
}
//有参构造器
Stock::Stock(const std::string& co, long n, double pr) {
company = co;
if (0 > n) {
std::cerr << "Number of shares can't be negatvie; "
<< company << "shares set to 0.\n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
/*
co 公司名称
n 股票数量
pr 单股价格
*/
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;
}
else
shares = n;
share_val = pr;
set_tot();
}
/*
买入股票
num 买入数量
price 单股价格
*/
void Stock::buy(long num, double price) {
//购买数量小于0,则提示错误信息
if (0 > num) {
std::cout << "Number of shares purchased cant't negative;"
<< "Transaction is aborted.\n";
}
else {
shares += num;
share_val = price;
set_tot();
}
}
//卖出
void Stock::sell(long num, double price) {
if (0 > num) {
std::cout << "Number of shares purchased cant't negative;"
<< "Transaction is aborted.\n";
}
else if (num > shares) {
std::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() const {
std::cout << "Company: " << company
<< " Shares: " << shares << '\n'
<< " Share Price: $" << share_val
<< " Total Worth: $" << total_val << '\n';
}
const Stock& Stock::topval(const Stock& s) const {
if (s.total_val > total_val)
return s;
return *this;
}
//当返回对象时,会直接创建新对象返回
const Stock Stock::copyNew() {
return *this;
}
在其他源文件中使用类和类方法.
#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.126);
fluffy_the_cat.show();
fluffy_the_cat.sell(400, 23.32);
fluffy_the_cat.show();
fluffy_the_cat.buy(300000, 40.125);
fluffy_the_cat.show();
fluffy_the_cat.sell(300000, 0.23);
fluffy_the_cat.show();
Stock myFluffy_1 = fluffy_the_cat.copyNew();
Stock myFluffy_2 = fluffy_the_cat.copyNew();
std::cout << "Fluffy one address is: " << &myFluffy_1
<< "\nFluffy two address is: " << &myFluffy_2 << std::endl;
return 0;
}
小细节:
1.如果是短小的成员函数,将被作为内联函数。
2.两个不同的对象,类成员和变量都是自己的,但是共享同一组类方法。
3.如果拥有有参构造器,必须声明无参构造器原型,通常应提供对类成员隐式初始化的默认构造函数。
4.不使用new创建的对象都在栈中,生命周期为其作用域,而new创建的则会分配在堆中,需要通过delete删除。
5.析构函数用来在销毁对象后的清理工作,声明为~Stock();
6.默认情况,将对象赋值给同类型的另一个对象,会将每个数据成员内容复制到目标对象中。
Stock stock1;//这会创建一个类对象,用默认构造器初始化它
stock1 = Stock("Tom",21,400);//这会创建一个临时对象,然后将其中的内容复制到stock1中
Stock* stock2 = new Stock;
Stock stock3 = {"Jim",22,3000};
7.当成员函数没有参数,无法确保调用对象不被修改时,应该这样声明函数:
void show() const;
void Stock::show() const{
//statments
}
该例子中,show中隐式的使用了类中的成员变量,所以需要显示的声明const。
8. 返回类型如果是对象则是返回其副本,而如果返回引用则是返回该对象。
对象数组
当程序创建未被显示初始化的类对象时,总是调用默认构造函数。
Stock mystuff[4]; //这里都会调用Stock() 默认构造器.
也可以使用构造函数进行批量的初始化
Stock stocks[10] = {
Stock("A",12.2,10),
Stock("B",32.1,20),
Stock("C",43.1,34),
Stock();
}
首先会创建默认构造函数,然后将花括号中的构造函数创建临时对象,然后将临时对象的内容复制到相应元素中,上面语句前三条将使用有参函数初始化,其余的都调用默认构造器初始化.
类作用域
定义成员函数的时候必须使用作用域解析运算符(::),使用类成员名时,需根据上下文使用直接运算符(.),间接成员运算符(->),或作用域解析运算符(::)。
如果类作用域中需定义常量,需要使用枚举类或者静态关键字来创建.
在对象未创建前,并没有实际的内存空间来创建常量。
static
private:
static const int Months = 12;
double costs[Months];
//通过静态关键字修饰变量,声明一个静态的常量值
该常量将与其静态变量存储在一起。
作用域内枚举
使用作用域内枚举类来实现静态变量:
class MyClassTest{
private:
enum class egg_c:short{Small,Medium,Large};
}
//类函数中使用
int kg = egg_c::Small;
//外部调用枚举
int kkg = Stock::egg_c::Small;