C++ Primer Plus第10章学习笔记

stock00.h
#pragma once
//10.1 stock00.h -- Stock class inter face
//version 00
#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; }	//设置total_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 // !STOCK00_H_
stock00.cpp
//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;
	}
	else
		shares = 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';
}
stock10.h
#pragma once
#ifndef STOCK10_H_
#define STOCK10_H_
#include<string>
#include<iostream>

//下面将构造函数和析构函数加入到类和方法的定义中
//鉴于添加构造函数的重大意义,这里将名称从stock00.h->stock10.h

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 string &co="Error",int n=0,double pr=0.0)
	这是默认构造函数的唯二两种定义方式
	为类定义了构造函数后,程序员就必须为它提供默认构造函数
	如果提供了非默认构造函数但没有提供默认构造函数
	则创建类对象的声明将会出错*/

	//为类定义了构造函数
	Stock(const std::string& m_company, long m_shares = 0, double m_share_val = 0.0);
	~Stock() { std::cout << "Bye-bye," << company << "!\n"; }
	//析构函数,一般将它编写为不执行任何操作的函数
	//此处是为了让您看出析构函数何时被调用

	/*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 // !STOCK10_H_
stock10.cpp
#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 shares can't 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 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 format
	cout.setf(orig, ios_base::floatfield);
	cout.precision(prec);
}
usestock1.cpp
#include "stock10.h"

int main()
{
	//如果没有这些大括号,代码块将为整个main(),因此仅当main()执行完毕后,才会调用析构函数
	//在窗口环境中,这意味着将在两个析构函数调用前关闭,导致您无法看到最后两条信息
	//添加这些大括号后,最后两个析构函数调用将在到达返回语句前执行,从而显示相应的信息
	{
		using std::cout;
		cout << "Using constructors to create new objects\n";
		//两种使用构造函数来初始化对象的方式
		//隐式地调用构造函数
		Stock stock1("NanoSmat", 12, 20.0);	//syntax 1
		stock1.show();
		//显式地调用构造函数
		Stock stock2 = Stock("Boffo Objects", 2, 2.0);	//syntax 2
		stock2.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 object
		//stock1对象已经存在,因此这条语句不是对stock1进行初始化,而是将新值赋给它
		//这是通过让构造程序创建一个新的、临时的对象,然后将其内容复制给stock1来实现
		//随后程序调用析构函数,以删除该临时对象
		//故输出如下所述:	Constructor using Nifty Foods called
		//				Bye - bye, Nifty Foods!
		//初始化语句与赋值语句有着根本性的差别,且初始化的方式效率更高
		cout << "Revised stock1:\n";
		stock1.show();
		cout << "Done\n";
	}
	return 0;
}

/*
Using constructors to create new objects
Constructor using NanoSmat called
Company: NanoSmat Shares: 12
Share Price: $20.000 Total Worth: $240.00
Constructor using Boffo Objects called
Company: Boffo Objects Shares: 2
Share Price: $2.000 Total Worth: $4.00
Assigning stock1 to stock2:
Listing stock1 and stock2:
Company: NanoSmat Shares: 12
Share Price: $20.000 Total Worth: $240.00
Company: NanoSmat Shares: 12
Share Price: $20.000 Total Worth: $240.00
Using a constructor to reset an object
Constructor using Nifty Foods called
Bye-bye,Nifty Foods!
Revised stock1:
Company: Nifty Foods Shares: 10
Share Price: $50.000 Total Worth: $500.00
Done
Bye-bye,NanoSmat!
Bye-bye,Nifty Foods!
*/

//由于这种自动变量被放在栈中,因此最后创建的对象将最先被删除,最先创建的对象将最后被删除
stock20.h
#pragma once
//增加了const成员函数和this指针
/*
	const Stock land=Stock("Kludgehorn Properies")
	land.show()
	对于当前的C++来说,编译器将拒绝第二行,因为show()的代码无法确保调用对象不被修改
	需要一种新的语法——保证函数不会修改调用对象
	C++的解决方法是将const关键字放在函数的括号后面。
	也就是说,show()声明应像这样:
	void show() const;	//promises not to change invoking object
	同样,函数定义的开头应像这样:
	void stock::show() const	//promises not to change invoking object
	只要类方法不修改调用对象,就应将其声明为const
	从现在开始,我们将遵守这一规则
*/
/*
	有时候方法可能涉及到两个对象,在这种情况下需要使用C++的this指针
	每个成员函数(包括析构函数和构造函数)都有一个this指针
	this指针指向调用对象
	如果方法要引用整个调用对象,则可以使用表达式*this
*/

#ifndef STOCK20_H_
#define STOCK20_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 m_company, long m_shares=0, double m_share_val=0.0);
	~Stock();
	void buy(long num, double price);
	void sell(long num, double price);
	void update(double price);
	void show() const;
	const Stock& topval(const Stock& s) const;
	/*该函数隐式地访问一个对象,而显示地访问另一个对象,并返回其中一个对象的引用
	括号中的const表明,该函数不会修改被显示地访问的对象
	而括号后地const表明,该函数不会修改被隐式地访问的对象
	由于该函数返回了两个const对象之一的引用,因此返回类型也应为const引用*/
};
#endif // !STOCK20_H_
stock20.cpp
#include<iostream>
#include "stock20.h"

//constructors
Stock::Stock()
{
	company = "no name";
	shares = 0;
	share_val = 0.0;
	total_val = 0.0;
}

Stock::Stock(const std::string m_company, long m_shares, double m_share_val)
{
	std::cout << "Constructor using " << m_company << " called\n";
	company = m_company;
	if (m_shares < 0)
	{
		std::cout << "Number of shares can't be negative;"
			<< company << "shares set to 0\n";
		shares = 0;
	}
	else
	{
		shares = m_shares;
	}
	share_val = m_share_val;
	set_tot();
}

Stock::~Stock()
{
}

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() const
{
	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 format
	cout.setf(orig, ios_base::floatfield);
	cout.precision(prec);
}

const Stock& Stock::topval(const Stock& s) const
{
	if (s.total_val > this->total_val)
		return s;
	else
		return *this;
}
usestock2.cpp
#include<iostream>
#include "stock20.h"

const int STKS = 4;
int main()
{
	//create an array of initialized objects
	Stock stocks[STKS] = {
		Stock("NanoSmart",12,20.0),
		Stock("Boffo Objects",200,2.0),
		Stock("Monolithic Oberlisks",130,3.25),
		Stock("Fleep Enterprises",60,6.5)
	};

	std::cout << "Stock hodings:\n";
	int st;
	for (st = 0; st < STKS; st++)
	{
		stocks[st].show();
	}
	const Stock* top = &stocks[0];
	/*
	* 指针和const,可以用两种不同的方式将const关键字用于指针
	* 第一种方法是让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值
	* 第二种方法是将指针本身声明为常量,这样可以防止改变指针指向的位置
	* 此处声明用的是第一种方法,top指向一个const Stock,因此不能用top来修改这个值
	*/
	for (st = 1; st < STKS; st++)
	{
		top = &(top->topval(stocks[st]));
	}
	std::cout << "\nMost valuable holding:\n";
	top->show();

	return 0;
}

/*
Constructor using NanoSmart called
Constructor using Boffo Objects called
Constructor using Monolithic Oberlisks called
Constructor using Fleep Enterprises called
Stock hodings:
Company: NanoSmart Shares: 12
Share Price: $20.000 Total Worth: $240.00
Company: Boffo Objects Shares: 200
Share Price: $2.000 Total Worth: $400.00
Company: Monolithic Oberlisks Shares: 130
Share Price: $3.250 Total Worth: $422.50
Company: Fleep Enterprises Shares: 60
Share Price: $6.500 Total Worth: $390.00

Most valuable holding:
Company: Monolithic Oberlisks Shares: 130
Share Price: $3.250 Total Worth: $422.50
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值