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." << '\n';
    }else{
      std::cout << ":hasn't a table." << '\n';
    };
    player2.Name();
    if (player2.HasTable()){
      std::cout << ":has a table" << '\n';
    }else{
      std::cout << ":hasn't a table." << '\n';
    };
    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 << '\n';};
};


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." << '\n';
    }else
    {
        std::cout << ": hasn't a table." << '\n';
    }

    std::cout << "Name:";
    rplayer1.Name();

    std::cout << "; Rating : " << rplayer1.Rating() << '\n';

    */
    TableTennisPlayer player1("Tara", "Boomdea", false);
    RatedPlayer rplayer2 (1212, player1);

    std::cout << "Name: ";
    rplayer2.Name();

    std::cout << "; Rating : " << rplayer2.Rating() << '\n';


    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;
}

 

 

 

未完待续...

 

posted @ 2018-07-04 14:23  我当道士那儿些年  阅读(3481)  评论(0编辑  收藏  举报