实现类成员函数
实现类成员函数还需要创建类描述的第二部分:为了那些由类声明中的原型表示的成员函数提供代码。成员函数定义与常规函数定义非常相似,它们都有函数头和函数体,也可以有返回类型和参数。但是它们还有两个特殊的特征:
- 定义成员函数时,使用作用域解析运算符(::)来标识函数所属的类;
- 类方法可以访问类的private组件。
首先,成员函数的函数头使用作用域运算符解析(::)来指出函数所属的类。例如,updata()成员函数的函数头如下:
void Stock::update(double price)
这种表示法意味着我们定义的update()函数是Stock类的成员。这不仅将update()标识为成员函数,还以为着我们可以将另一个类的成员函数也命名为update()。例如,Buffoon()类的update()函数的函数头如下:
void Buffoon::update()
因此,作用域解析运算符确定了方法定义对应的类的身份。标识符update()具有类作用域(class scope)。Stock类的其他成员函数不必使用作用域解析运算符,就可以使用update()方法,这是因为它们属于同一个类,因此update()是可见的。然而,在类声明和方法定义之外使用update()时,需要采取特殊的措施,稍后将作介绍。
类方法的完整名称中包括类名。我们说。Stock::update()是函数的限定名;而简单的update()是全名的缩写(非限定名),它只能在类作用域中使用。
方法的第二个特点是,方法可以访问类的私有成员。例如,show()方法可以使用这样的代码:
std::cout<<"Company:"<<company
<<"Shares:"<< shares <<endl;
<<"Share Price:$"<<share_val
<<"Total Worth:$"<<total_val<<endl;
其中,company,shares等都是Stock类的私有数据成员。如果试图使用非成员函数访问这些数据成员,编译器将禁止(友元函数例外)。
了解这两点后,就可以实现类方法了。将它们放在了一个独立的实现文件中,因此需要包含在头文件stock00.h,让编译器能够访问类定义。为让您获得更多有关名称空间的经验,在有些方法中使用了限定符std::,在其他方法中泽使用using声明。
#include <iostream>
#include "stock00.h"
void Stock::acquire(const std::string &co,long n,double pr)
{
company = co;
if(n<0)
{
std::cout<<"Numer of shares can't be negative;"<<company
<<"shares set to be 0."<<std::endl;
}
else
{
shares = n;
}
share_val = pr;
set_tot();
}
void Stock::buy(long num,double price)
{
if(num<0)
{
std::cout<<"Numer of shares can't be negative,Transaction is aborted"
<<std::endl;
}
else
{
shares += num;
share_val = price;
set_tot();
}
}
void Stock::sell(long num,double price)
{
if(num<0)
{
std::cout<<"Numer of shares can't be negative,Transaction is aborted"
<<std::endl;
}
else if(num >shares)
{
std::cout<<"You can't sell more than you have!Trancsaction is aborted"
<<std::endl;
}
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<<std::endl;
std::cout<<"Shares:"<<shares<<std::endl;
std::cout<<"Share price"<<share_val<<std::endl;
std::cout<<"Total worth:"<<total_val<<std::endl;
}
1.成员函数说明
acquire()函数管理对某个公司股票的首次购买,而buy()和sell()管理增加或者减少持有的股票、方法buy()和sell()确保买入或卖出的股数不为负数。另外,如果用户试图卖出超过他持有的股票数量,则sell()函数将结束这次交易。这种使数据私有并且限制于对公有函数访问的技术允许我们能够控制数据如何被使用;在这个例子中,它允许我们加入这些安全防护措施,避免不适当的交易。
4个成员函数设置或重新设置了total_val成员值。这个类并非将计算代码编写4次,而是让每个函数都调用set_tot()函数。由于set_tot()只是实现代码的一种方式,而不是公有接口的组成部分,因此这个类将其声明为私有成员函数。如果这个计算代码很长,则这种方式还可以省去许多输入代码的工作,并可节省空间。然而,这种方法的主要价值在于,通过使用函数调用,而不是每次重新输入计算代码,可以确保执行的计算完全不同。另外,如果必须修订计算代码,则只需在一个地方进行修改即可。
2.内联方法
其定义位于类声明中的函数都将自动成为内联函数,因此Stock::set_tot()是一个内联函数。类声明常将短小的成员函数作为内联函数,set_tot()符合这样的要求。
如果愿意,也可以在类声明之外定义成员函数,并使其成为内联函数。为此,只需要在类实现部分中定义函数时使用inline限定符即可。