• c++ 的类 和 类继承, 什么是c++中的基类和派生类?


    闲云潭影日悠悠,物换星移几度秋

    你既然已经做出了选择, 又何必去问为什么选择。鬼谷绝学的要义, 从来都不是回答, 而是抉与择

    普通类

    #ifndef TABTENN0_H_
    #define TABTENN0_H_
    
    #include <string>
    
    using namespace std;
    
    class TableTennisPlayer
    {
    private:
        string firstname;
        string lastname;
        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;};
    };
    
    
    #endif
    tabtenn0.h
    #include <iostream>
    #include <string>
    #include "tabtenn0.h"
    
    using namespace std;
    
    TableTennisPlayer::TableTennisPlayer(const string & fn, const string & ln, bool ht): firstname(fn), lastname(ln), hasTable(ht) {}
    
    void TableTennisPlayer::Name () const
    {
        std::cout << lastname << "," << firstname ;
    }
    tabtenn0.cpp
    #include <iostream>
    #include "tabtenn0.h"
    
    using namespace std;
    
    int main (int argc, char const *argv[])
    {
        TableTennisPlayer player1("Chuck", "Blizzard", true);
        TableTennisPlayer player2("Tara", "Boomdea", false);
        player1.Name();
        if (player1.HasTable()){
          std::cout << ":has a table." << '
    ';
        }else{
          std::cout << ":hasn't a table." << '
    ';
        };
        player2.Name();
        if (player2.HasTable()){
          std::cout << ":has a table" << '
    ';
        }else{
          std::cout << ":hasn't a table." << '
    ';
        };
        return 0;
    }
    usett0.cpp

    继承类

    基类的private成员都不能被派生类访问。

    声明为public的方法和属性可以被随意访问;

    声明为protected的方法和属性只能被类本身和其子类访问;

    而声明为private的方法和属性只能被当前类的对象访问。  

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Father
    {
    private:
            string first_name;
            string last_name;
    public:
            Father(string fn, string ln): first_name(fn), last_name(ln) {};
            void Name() {std::cout << first_name  << ","<< last_name << '
    ';};
    };
    
    
    class Son: public Father  // 这句很重要呀
    {
    private:
    
    public:
            Son(string an, string bn):Father(an, bn){};
    };
    
    int main(int argc, char const *argv[])
    {
        // Father father("张三", "李四");
        // father.Name();
    
        Son son("张三", "李四");
        son.Name();
    
        return 0;
    }
    继承类写法

    下面这个是两种展示调用基类方法的方式很有意思, 设计到拷贝构造和深浅拷贝, 有兴趣可以百度下

    #ifndef TABTENN1_H_
    #define TABTENN1_H_
    #include <string>
    
    using namespace std;
    
    class TableTennisPlayer
    {
    private:
        string firstname;
        string lastname;
        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;};
    };
    
    
    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
    tabtenn1.h
    #include <iostream>
    #include "tabtenn1.h"
    
    TableTennisPlayer::TableTennisPlayer (
      const string & fn,
      const string & ln,
      bool ht):firstname(fn), lastname(ln), hasTable(ht) {}
    
    void TableTennisPlayer::Name() const
    {
        std::cout << lastname << ", " << firstname ;
    }
    
    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) {}
    
    /*
    问题是上面这个类方法函数:
    RatedPlayer::RatedPlayer(
      unsigned int r,
      const TableTennisPlayer & tp
    ):TableTennisPlayer(tp), rating(r) {}
    
    的TableTennisPlayer(tp) 是不是等于 TableTennisPlayer = tp的意思
    
    但是usett1.cpp 里面传入以后player1的作用是什么?
    
    */
    tabtenn1.cpp
    #include <iostream>
    #include <string>
    #include "tabtenn1.h"
    
    using namespace std;
    
    int main(int argc, char const *argv[])
    {
    
        /*
        TableTennisPlayer player1("Tara", "Boomdea", false);
        RatedPlayer rplayer1(1140, "Mallory", "Duck", true);
        rplayer1.Name();
    
    
        if (rplayer1.HasTable())
        {
            std::cout << ": has a table." << '
    ';
        }else
        {
            std::cout << ": hasn't a table." << '
    ';
        }
    
        std::cout << "Name:";
        rplayer1.Name();
    
        std::cout << "; Rating : " << rplayer1.Rating() << '
    ';
    
        */
        TableTennisPlayer player1("Tara", "Boomdea", false);
        RatedPlayer rplayer2 (1212, player1);
    
        std::cout << "Name: ";
        rplayer2.Name();
    
        std::cout << "; Rating : " << rplayer2.Rating() << '
    ';
    
    
        return 0;
    }
    usett1.cpp

    分为三种:

    {

      公有继承,

      保护继承,

      私有继承

    }

    从一个类派生出另一个类时, 原始类成为基类, 继承类成为派生类。粗俗的讲:子继承父, 父就是基类, 子就是派生类

    这说明继承, 首先需要一个基类。

    对于公有派生, 派生类对象包含基类对象, 基类的公有成员将成为派生类的公有成员;

    基类的私有部分也将成为派生类的一部分, 但只能通过基类的公有和保护方法访问。换句话说: "派生类不能访问基类的私有成员, 必须通过基类的方法进行"

    简单写法

    class RatedPlayer: public TableTennisPlayer
    {
      private:
    
      public:
    
    };

    构造函数

    RatedPlayer::RatedPlayer(
      unsigned int r, 
      const string & fn, 
      const string & fn, 
      cosnt string & ln, 
      bool ht
    ): TableTennisPlayer(fn, ln, ht) // 初始化基类构造函数, 或者说成员初始化列表
    {
        rating = r;
    }

    // 如果赋值RatedPlayer rplayer(1140, "Mallory", "Duck", true),
    // 同时将“Mallory”, "Duck" 和 true赋给fn、ln和ht作为实参传递给TableTennisPlayer构造函数

     

    如果省略成员初始化列表, 将会怎么样?

    RatedPlayer::RatedPlayer(
      unsigned int r, 
      const string & fn, 
      const string & fn, 
      cosnt string & ln, 
      bool ht
    )
    {
        rating = r;
    }
    如果不调用基类构造函数, 与下面代码等效, 程序将使用默认的基类构造函数
    RatedPlayer::RatedPlayer(
      unsigned int r, 
      const string & fn, 
      const string & fn, 
      cosnt string & ln, 
      bool ht
    ): TableTennisPlayer() // 程序将使用默认的基类构造函数, 上面代码与此等效
    {
        rating = r;
    }

    注意: 除非要使用默认构造函数, 否则应显式调用正确的基类构造函数。

    RatedPlayer::RatedPlayer(
      unsigned int r, 
      const string & fn, 
      const string & fn, 
      cosnt string & ln, 
      bool ht
    ): TableTennisPlayer(tp) 
    {
        rating = r;
    }

    未完待续...

  • 相关阅读:
    Javascript快速入门(上篇)
    Linux快速入门01-基础概念
    正则表达式快速入门
    Sublime快速入门
    centos 6.5 git 服务器的配置(入门级)
    centos6.5 网卡的处理
    centos 6.5 u盘 安装问题 :vesamenu.c32: Not a COM32R image
    ubuntu 14.04 对exfat的支持
    [转]ubuntu 14.04 如何开启和关闭触控板
    ubuntu 下mongodb安装
  • 原文地址:https://www.cnblogs.com/renfanzi/p/9262369.html
Copyright © 2020-2023  润新知