zoukankan      html  css  js  c++  java
  • c/c++ -->对象和类

    1、类基础

     1.1 基本概念

    类是由数据结构和方法组成的,方法就是对数据结构进行处理。

    类由.h文件和.cpp文件组成,.h文件中表明该类的基本接口,.cpp文件实现具体的方法。

    通过类可以创建具体的对象,通过对象来调用方法。

    比如:求正方形的面积。

    其中,"正方形"就是一个类,正方形的边长"a"就是数据,面积"S = a * a"就是方法。

    而"正方形A的边长为5mm"就是代表一个对象的数据为多少,调用方法即可求出面积为25mm2

    1.2 一个类的基本组成部分

    #ifndef  __HEAD_H__
    #define __HEAD_H__
    
    //使用class关键字,"Stock"为类名,一般来说类名首字母大写
    class Stock
    {
    //"private"标识私有类成员,外部不可访问,达到数据隐藏的目的
    private:
        long val;
        void set_num();
    //"public"标识公共类成员,外部可访问
    public:
    //构造函数,新建对象时默认调用
        Stock();
    //析构函数,释放对象时默认调用
        ~Stock();
        void show();
    };
    
    #endif

    类虽然是数据隐藏,但还是将内部数据也一并写在了类结构里。这是因为每新建对象时,都会新建私有数据,各个对象使用各自的数据,共用公共的方法

    实现类成员函数如下所示:

    //head.cpp
    #include "head.h"
    
    //使用"函数返回 类名::函数名()"的方式实现一般函数
    void Stock::show()
    {
    
    }
    void Stock::set_num()
    {
    
    }
    //使用"类名::类名()"的方式实现构造函数
    Stock::Stock()
    {
        val = 0;
    }
    //使用"类名::~类名()"的方式实现析构函数
    Stock::~Stock()
    {
        
    }

    类的使用如下所示:

    //use.cpp
    #include "head.h"
    
    int main()
    {
        Stock use_class;
    
        use_class.show();
    
      return 0;  
    }

    1.3需要注意的几点

    1)、当构造函数具有参数时,需要在创建对象时为其指定参数值。

    //假设构造函数声明如下
    Stock(const string & co, long n, double pr);
    
    //则在创建对象时有如下使用几种方式
    
    //此种方式,编译器可能创建一个临时对象,给food赋值后,又删除该临时对象
    Stock food = Stock("World Cabbage", 250, 1.25);
    //也可以使用构造函数给对象赋新值,这种方式一定会创建临时对象
    food = Stock("Nifty Foods", 50, 1.25);
    
    Stock food("World Cabbage", 250, 1.25);
    Stock *pfood = new Stock("World Cabbage", 250, 1.25);
    
    Stock food = {"World Cabbage", 250, 1.25} //c++11
    Stock food {"World Cabbage", 250, 1.25} //c++11
    Stock *pfood = new Stock{"World Cabbage", 250, 1.25} //c++11
    
    //创建对象数组时
    const int STKS = 4;
    Stock stocks[STKS] = 
    {
    Stock("NanoSmart", 12.5, 20),
    Stock("Boffo", 12.5, 20),
    Stock("Foods", 12.5, 20),
    Stock("World", 12.5, 20),
    };

    当前也可以给构造函数所有参数默认值或者利用函数重载来避免创建对象时显示的调用构造函数。

    2)、只要类方法不修改调用对象,就应该将其声明为const成员函数。

    //声明
    void show() const;
    //定义
    void Stock::show() const
    {
    
    }

    3)、如果构造函数使用了new,则析构函数必须提供delete。

    4)、当方法需要引用对象时,使用this指针,代表当前对象的地址。

    1.4 运算符重载

    运算符重载,就是用户将运算符扩展功能,编译器根据操作数来确认如何操作。

    函数格式为: operatorop(argument list)

    //time.h
    #ifdef __TIME_H__
    #define __TIME_H__
    class Time
    {
    private:
      int hours;
      int minutes;
    public:
      Time operator+(const Time & t) const;    
    }
    #endif
    
    //time.c
    Time Time::operator+(const Time & t) const
    {
      Time sum;
       sum.minutes = minutes + t.minutes;
       sum.hours = hours + t.hours + sum.minutes / 60;
       sum.minutes %= 60;
       return sum;  
    }

    使用如下:

    Time total;
    Time fixing;
    Time coding;
    
    total = coding + fixing;
    
    //等价于
    total = coding.operator+(fixing);

    需要注意的是:

    1)、重载后的运算符必须至少有一个操作数是用户定义的类型,防止用户为标准类型重载运算符。

    2)、使用运算符时不能违反运算符原来的句法规则

    3)、不能创建新的运算符

    4)、注意使用的顺序

    比如:

    A = B * 2.75//解析为
    A = B.operator*(2.75);
    
    //不能写成
    A = 2.75 * B;

    1.5 友元

    1.6继承

    通过类继承,可以使用基类的方法及部分数据,简化编程。从一个类派生出另一个类时,原始类称为基类,继承类称为派生类。

    //tabtebb1.h
    #ifndef TABTENN1_H__
    #define TABTENN1_H__
    #include <string>
    using std::string;
    //simple base class
    class TableTennisPlayer
    {
    private:
      string firstname;
      string lasename;
      bool    hasTable;
    public:
      TableTennisPlayer(const string &fn = "none",
      const string & ln = "none", bool ht = false);
      void Name() const;
      bool HasTable() const {return hasTable;}
      void ResetTable(bool v){hasTable = v;}    
    };
    //simple derived class
    class RatedPlayer : public TableTennisPlayer
    {
    private:
      unsigned int rating;
    public:
      RatedPlayer(unsigned int r = 0, const string & fn = "none",
      const string & ln = "none", bool ht = false);
      RatedPlayer(unsigned int r, const TableTennisPlayer & tp);
      unsigned int Rating() const {return rating;}
      void ResetRating (unsigned int r){rating = r;}
    };
    #endif
    : public TableTennisPlayer 指出RatedPlayer类的基类是TableTennisPlayer,public指出TableTennisPlayer是一个公有基类,称为公有派生。
    使用共有派生,基类的共有成员将称为派生类的共有成员。基类的私有部分也将成为派生类的一部分,但是只能通过基类的公有和保护方法(protected)访问。

    创建派生类对象时,必须先创建基类对象:
    //通过成员初始化列表调用基类的构造函数,然后再初始化派生类私有数据
    //如果没有初始化列表,则编译器使用默认的基类构造函数
    RatedPlayer::RatedPlayer(unsigned int r, const string & fn, const string & ln, bool ht) : TableTennisPlayer(fn, ln, ht)
    {
      rating = r;
    }
    
    //调用基类的复制构造函数
    RatedPlayer::RatedPlayer(unsigned int r, const TableTennisPlayer & tp)
    : TableTennisPlayer(tp)
    {
      rating = r;
    }
    释放对象与创建对象的顺序相反,即先执行派生类的析构函数,再调用基类的析构函数。 
    
    
    
  • 相关阅读:
    server2012/win8 卸载.net framework 4.5后 无法进入系统桌面故障解决【转】
    Entity Framework中AutoDetectChangesEnabled為false時更新DB方法
    git常用命令备忘录
    MSSQL日誌傳輸熱備份注意事項
    c#生成唯一编号方法记录,可用数据库主键 唯一+有序
    Angular 隨記
    使用dumpbin命令查看dll导出函数及重定向输出到文件【轉】
    UML类图与类的关系详解【转】
    知識隨記
    session不会过期
  • 原文地址:https://www.cnblogs.com/KcMeterCEC/p/6371926.html
Copyright © 2011-2022 走看看