http://210.44.195.12/cgyy/text/HTML/text/20.htm
类:
类申明:以数据成员的方式描述数据部分,以成员函数(被称为方法)的方式描述公有接口。
类方法定义:描述如何实现类成员函数。
简单的说:类声明提供了类的蓝图,而方法定义则提供了细节。
使用类,必须了解公共接口,编写类,必须创建公共接口。
控制成员访问:公有还是私有
无论类成员是数据还是成员函数,都可以在类的共有或私有部分中声明,但是由于隐藏数据是OOP的主要目标之一,因此,数据项通常放在私有部分,组成类接口的成员函数放在公有部分。
类的定义:
定义成员函数时:使用作用域解析操作符::来标识函数所属的类;
类方法可有访问类的private组建。
注意:调用成员函数时,它将使用被用来调用它的对象的数据成员。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
可以说这是一个面向对象编程的最基本的问题。我不想引进一大堆的慨念。这里只打一个形象的比方。
类其实就是一辆已装配好的自行车,自行车在基本组成方面有前后轮,坐椅,后坐,脚登板,方向盘等,在功能方面有脚登板,前后轮,方向盘的
转动和自行车的移动等;在这里,前后轮,坐椅,后坐,脚登板,方向盘就是类的数据成员,数据成员有私有的(private),保护的
(protected),公有的(public);前后轮就是类的私有数据成员(因为它不可以被外界访问),坐椅,后坐,脚登板,方向盘就是类的公有的数
据成员(因为它可以被外界访问);
类里负责操纵数据成员或提供一些功能的函数就是类的成员函数。在这里,脚登板,前后轮,方向盘的转动和自行车的移动功能就是类的成员函
数。类还有友元类,一个友元类可以访问类的私有数据,而非友元类则不能访问类的私有数据,这就实现了类的封装(就象包装好的自行车一样)。类可以派生,现
在你想造一辆能用马力拉的又具有自行车
特征的机器,这个机器就是自行车的派生类,它继承了自行车的一切特征但又具有一些扩展的功能,派生类可以访问父类的数据成员,重载父类的成员函数,实现父类虚函数的功能等。好了,就说到这吧,将得不好,别见笑,有错误的话请指正。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <cstring>
using namespace std;
class Stock //class declaration
{
private:
char company[30];
int shares;
double share_val;
double total_val;
void set_tot(){ total_val=shares*share_val;}
public:
// Stock();
void acquire(const char *co,int n,double pr);
void buy ( int num, double price);
void sell (int num, double price);
void update ( double price);
void show();
}; //note semicolon at the end;
void Stock::acquire(const char * co,int n,double pr)
{
strncpy(company, co, 29); //truncate co to fit company;
company[29] = '/0';
if (n <0)
{
cerr << "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(int num,double price)
{
if (num <0)
{
cerr << "Number or shares purchased can't be negative. "
<< "Transaction is aborted./n";
}
else
{
shares += num;
share_val = price;
set_tot();
}
}
void Stock::sell(int num, double price)
{
using std::cerr;
if (num<0)
{
cerr <<" Number of shares sold can't be negative."
<< "Transaction is aborted./n";
}
else if (num > shares)
{
cerr << "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()
{
cout << "Company: " << company << " shares:" << shares <<endl
<< " share price: $" << share_val
<< " Total worth:$" << total_val << endl;
}
int main()
{
Stock stock1;
stock1.acquire("NanoSmart", 20, 12.5);
cout.setf(ios_base::fixed);
cout.precision(2);
cout.setf(ios_base::showpoint);
stock1.show();
stock1.buy(15,18.25);
stock1.show();
stock1.sell(400,22.00);
stock1.show();
return 0;
}
///////////////////////////////
函数模板
函数的重载可以实现一个函数名多用,将实现相同的或类似功能的函数用同一个函数名
来定义。这样可以使编程者在调用同类函数时感到含义清楚,方法简单。但是在程序中仍然要分别定义每一个函数,如例1.6的程序中三个max函数的函数体是
完全相同的,只是形参的类型不同,也要分别定义。有些读者自然会想到,对此能否再简化呢?
为了解决这个问题,C++提供了函数模板(function
template)。所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。
凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只须在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,
从而实现了不同函数的功能。
例8 将例6中的程序改为通过函数模板来实现。
#include<iostream>
using namespace std;
template<typename T>; //模板声明,其中T为类型参数
T max(T a,T b,T c) //定义一个通用函数,用T作虚拟的类型名
{ if(b>a)a;b:
if(c>a)a:c;
return a:
}
int main()
{ int i1=8,i2=5,i3=6,i;
double dl=56.9,d2=90.765,d3=43.1,d;
long g1=67843,g2=-456,g3=78123,g;
i=max(i1,i2,i3); //调用模板函数,此时T被int取代
d=max(d1,d2,d3); //调用模板函数,此时T被double取代
g=max(8l,S2,83); //调用模板函数,此时T被long取代
cout <<"i_max="<<i <<endl;
cout<<"f_max="<< f << endl;
cout<< "g_max="<<g <<endl;
return ();}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include <iostream>
using namespace std;
template <typename T>
T max(T a,T b, T c)
{
a=a>b?a:b;
a=a>c?a:c;
return a;
}
int main(int argc, char** argv)
{
int i1=8,i2=5,i3=6,i;
double d1=56.9,d2=90.88,d3=1029.77,d;
long g1=33333,g2=76865656,g3=6789,g;
i=max(i1,i2,i3);
d=max(d1,d2,d3);
g=max(g1,g2,g3);
cout << "i_max=" << i << endl;
cout << "f_max=" << d << endl;
cout << "g_max=" << g << endl;
return 0;
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
运行结果与例6相同。为了节省篇幅,数据不用cin语句输入,而在变量定义时初始化。程序第3-8行是定义模板。定义函数模板的一般形式为
template<typename T> 或template<class T>
通用函数定义 通用函数定义。
class和typename的作用相同,都是表示“类型名”,二者可以互换。以前的C++程序员都用class。typename是不久前才被加到标准
C++中的,因为用class容易与C++中的类混淆。而用typename其含义就很清楚,肯定是类型名(而不是类名)。
可能对模板中通用函数的表示方法不习惯,其实在建立函数模板时,只要将例6程序中定义的第一个函数首部的int改为T即可。即用虚拟的类型名T代替具体的
数据类型。在对程序进行编译时,遇到第13行调用函数max(i1,i2,i3),编译系统会将函数名max与模板max相匹配,将实参的类型取代函数模
板中的虚拟类型T。此时相当于已定义了一个函数:
int max(int a,int b,int c)
{ if(b>a) a=b;
if(c>a) a=c;
return a;
}
然后调用它。后面两行(14,15行)的情况类似。
类型参数可以不只一个,可根据需要确定个数。如
template<class T1,typename T2>
可以看到,用函数模板比函数重载更方便,程序更简洁。但应注意它只适用于函数的参数个数相同而类型不同,且函数体相同的情况,如果参数的个数不同,则不能用函数模板。