具有私有成员的类是具有基类指针的模板?

时间:2017-04-14 23:47:10

标签: c++

嗨我需要对一些代码做一些澄清,因为谷歌没有帮助也没有做过任何我的C ++书籍。好的我有一个基类,我派生了2个其他类,但我没有在这里发布代码,因为它们与我的问题没有任何关系:

ifndef BASEBALLPLAYER_H
#define BASEBALLPLAYER_H

#include <iostream>

using namespace std;

class BaseBallPlayer{                                           //abstract class meaning no instance can be made for it, which is why we access it via derived classes

                                                                //data members
protected:
    string name;
    int height;
    int weight;


public:

    BaseBallPlayer();
    BaseBallPlayer(string nam, int wight, int hight);
    string get_Name();
    virtual void print_player()=0;                                      // 
    virtual void load_player(ifstream & read) = 0;                      // 

    virtual ~BaseBallPlayer();                                          
};

然后是一个ArrayList.h文件:

#ifndef ARRAY_LIST_H
#define ARRAY_LIST_H
#include <string>

using namespace std;
const static int MAX_INIT = 99;

    template <class elemType>
    class ArrayList {
    private:
        int n_element;
        elemType * data;

    public:
        ~ArrayList();
        ArrayList(int n = MAX_INIT);
        ArrayList(const ArrayList<elemType> &);
        const ArrayList<elemType> & operator=(const ArrayList<elemType> &);
        void MakeEmpty();
        bool IsFull() const;
        int  LengthIs() const;
        void RetrieveItem(elemType &, bool&);
        void InsertItem(elemType);
        void DeleteItem(elemType);
        void ResetList();
        bool IsLastItem();
        void GetNextItem(elemType &);
    };

现在我的问题在于我在PlayerDatabase.h文件中创建的这个新类,它是一个独立的类:

#ifndef PLAYERDATABASE_H
#define PLAYERDATABASE_H

#include <iostream>
#include "BaseBallPlayer.h"
#include "ArrayList.h"

using namespace std;

    class PlayerDatabase{

    private:
        ArrayList<BaseBallPlayer *> teamArrayList; // I do NOT Understand what this means?

    public:

    };
    #endif

我不明白我的PlayerDatabse.h文件中的私有成员意味着什么或需要什么?我能用它做什么?我的导师告诉我们用指针使用该模板,但我没有机会问它的含义是什么意思?

2 个答案:

答案 0 :(得分:3)

所以我不确定你最终的目标是什么,但让我快速猜测你可能会尝试做什么:

所以你提到你有BaseBallPlayer的2个子类,让我们说它们是MajorLeaguePlayerMinorLeagePlayer这个私有数组列表teamArrayList可以用来保存基类的任意组合(BaseBallPlayer - 在您的情况下为MajorLeaguePlayerMinorLeaguePlayer)。

您通常希望将此teamArrayList保留为私有,以便只有公共方法才能安全地修改它。例如,您可能想要PlayerDatabase的构造函数,其参数为ArrayList<BaseBallPlayer *>

PlayerDatabase(ArrayList<BaseBallPlayer *> players) {
  // set the private teamArray list in the constructor
  teamArrayList = players;
}

或者您可能希望根据基类BaseBallPlayer

中的一个属性对teamArray列表进行排序
// or another one sorting for weight or name
void sortPlayerListByHeight() {
  // sort the private team array list
  teamArrayList = ... // sort by height
}

也许你想获得列表中的玩家数量,或者找到列表中的第一个或最后一个玩家。一般来说,使用公共方法访问/修改私有数据成员(即teamArrayList)是一种很好的做法

int numberOfPlayersInList() {
  return teamArrayList.LengthIs();
}

BaseBallPlayer getFirstPlayerInList() {
  return teamArrayList.RetrieveItem.... // get the first item in the list
}

然后从另一个类中构建一些子类对象并构建播放器数据库:

ArrayList<BaseBallPlayer *> playerList = new ArrayList<>();
playerList.add(new MinorLeagePlayer("minorName", 180,70);
playerList.add(new MajorLeaguePlayer("majorName", 200, 72);
PlayerDatabase db = new PlayerDatabase(playerList);

// now you can do some operations on the PlayerDatabase knowing that the list will contain all objects that can use methods from the Base Class (`BaseBallPlayer`)

db.getFirstPlayerInList().print_player(); // method from your base class implemented in your subclasses


int numberOfPlayers = db.numberOfPlayersInList();
// do something with the number of players in the list

这是伪代码,但希望它能帮助你理解。

与我们的评论相关的修改:

ArrayList<BaseBallPlayer *> *playerList = new ArrayList<BaseBallPlayer *>();
MinorLeaguePlayer *aPlayer = new MinorLeaguePlayer();
playerList->InsertItem(aPlayer);

我在ArrayList构造函数,MinorLeaguePlayer构造函数和InsertItem方法中包含了几个简单的cout语句,以便在调用它们时输出一些信息(我假设你已经有了这些方法的实现) ):

ArrayList构造函数:n_element = n; cout << "Constructing the arrayList, n_element = " << n_element << endl;

MinorLeaguePlayer构造函数:cout << "Constructing a minor league player" << endl;

InsertItem方法:cout << "Inserting an item into the ArrayList" << endl;

以下是构建并运行上述代码后的输出:

Constructing the arrayList, n_element = 99
Constructing a minor league player
Inserting an item into the ArrayList

编辑2与进一步评论相关:

引用elemType

的方法

示例:

// this will basically just going to "hold" the BaseBallPlayer fetched
// from GetNextItem
BaseBallPlayer *bPlayer; 
playerList->GetNextItem(bPlayer);
cout << "Weight after fetching from list = " << bPlayer->weight << endl;

GetNextItem的实现看起来像这样:

void ArrayList<elemType>::GetNextItem(elemType& player) {
// implementation to get the next item in the array list
player = //... set the "NextItem" to the BaseBallPlayer reference we passed into this method
}

编辑3:print_player()多态:

MinorLeaguePlayer *minPlayer = new MinorLeaguePlayer();
MinorLeaguePlayer *min2Player = new MinorLeaguePlayer();
MajorLeaguePlayer *majPlayer = new MajorLeaguePlayer();
MajorLeaguePlayer *maj2Player = new MajorLeaguePlayer();
playerList->InsertItem(minPlayer);
playerList->InsertItem(min2Player);
playerList->InsertItem(majPlayer);
playerList->InsertItem(maj2Player);

BaseBallPlayer *fetchedPlayer;
for (int i = 0; i < 4; i++) {
    playerList->GetNextItem(fetchedPlayer);
    fetchedPlayer->print_player();

}

请注意,在调用print_player()方法之前,您必须获取对fetchedPlayer的引用

playerList->GetNextItem(fetchedPlayer);
fetchedPlayer->print_player();

这是因为您的GetNextItem方法的结构方式是将对nextItem的引用放在传入的BaseBallPlayer中。

这是另一个示例,该方法将返回BaseBallPlayer而不是通过引用设置它:

method stub (in ArrayList):
elemType getNextItemReturn();

for loop:
for (int i = 0; i < 4; i++) {
    playerList->getNextItemReturn()->print_player();
}

这是一个快速讨论的链接,询问哪个更有效: Which is more efficient: Return a value vs. Pass by reference?

带有示例cout语句的输出:

Constructing the arrayList, n_element = 99
Inserting an item into the ArrayList
Inserting an item into the ArrayList
Inserting an item into the ArrayList
Inserting an item into the ArrayList
Printing From MINOR League Player
Player Name: MinorLeagueName Weight = 22
Printing From MINOR League Player
Player Name: MinorLeagueName Weight = 22
Printing From MAJOR League Player
Player Name: MajorLeaguePlayer Weight = 33
Printing From MAJOR League Player
Player Name: MajorLeaguePlayer Weight = 33

print_player()的模拟实现:

void MinorLeaguePlayer::print_player() {
    cout << "Printing From MINOR League Player" << endl;
    cout << "Player Name: " << name << " Weight = " << weight << endl;
}

void MajorLeaguePlayer::print_player() {
    cout << "Printing From MAJOR League Player" << endl;
    cout << "Player Name: " << name << " Weight = " << weight << endl;
}

答案 1 :(得分:1)

*** Error in `./a.out': free(): invalid pointer: 0x00007ffd003f62b0 *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fdb2e5497e5] /lib/x86_64-linux-gnu/libc.so.6(+0x7fe0a)[0x7fdb2e551e0a] /lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fdb2e55598c] ./a.out[0x4012d6] 是指向teamArrayList个对象的指针列表。通过使用指针,它可以通过多态 - 指针可以指向从BaseBallPlayer派生的任何类。

这是使用抽象基类的常用方法。然后,您可以使用它来调用BaseBallPlayer类中的方法,并使用相应派生类中的实现。