C++学习之----;类

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>
    可以看到,用函数模板比函数重载更方便,程序更简洁。但应注意它只适用于函数的参数个数相同而类型不同,且函数体相同的情况,如果参数的个数不同,则不能用函数模板。

发布了39 篇原创文章 · 获赞 7 · 访问量 11万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章