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

Class With A Private Member Being A Template With A Base Class Pointer?

本文关键字:指针 成员 基类      更新时间:2023-10-16

嗨,我需要对一些代码进行一些澄清,因为谷歌没有帮助,我的任何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 个BaseBallPlayer子类,假设它们是MajorLeaguePlayer的,并且MinorLeagePlayer这个私有数组列表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 语句,以便在调用它们时输出一些信息(我假设您已经实现了这些方法):

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

小联盟球员构造器:cout << "Constructing a minor league player" << endl;

插入项方法: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();
}

这是一个快速讨论的链接,询问哪个更有效率: 哪个更有效:返回值与按引用传递?

以及带有示例 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;
}

teamArrayList是指向BaseBallPlayer对象的指针列表。通过使用指针,它可以通过多态- 指针可以指向从BaseBallPlayer派生的任何类。

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