在类的函数之外归档向量

Filing a vector outside of a function in a class

本文关键字:向量 函数      更新时间:2023-10-16

这里相当简单的问题,在类。cpp文件中填充函数之外的矢量的最佳方法是什么?目前,我正在尝试以下不工作:

std::vector<Player> midfielder(8);
midfielder.at(0) = Midfielder("Default         ",0,"Midfielder");
midfielder.at(1) = Midfielder("David Armitage  ",1,"Midfielder");
midfielder.at(2) = Midfielder("Tom Rockliff    ",2,"Midfielder");
midfielder.at(3) = Midfielder("Gary Ablett     ",3,"Midfielder");
midfielder.at(4) = Midfielder("Dyson Heppel    ",4,"Midfielder");
midfielder.at(5) = Midfielder("Scott Pendlebury",5,"Midfielder");
midfielder.at(6) = Midfielder("Michael Barlow  ",6,"Midfielder");
midfielder.at(7) = Midfielder("Jack Steven     ",7,"Midfielder");

为了提供上下文,'中场'是一个继承自'球员'类的类。

TeamManagment.h

#ifndef TEAMMANAGEMENT_H
#define TEAMMANAGEMENT_H
#include <vector>
#include "Player.h"
#include "Midfielder.h"
#include <string>
class TeamManagement
{
    public:
        TeamManagement();

        void Display_Players();
};
#endif // TEAMMANAGEMENT_H

TeamManagement.cpp

#include <iostream>
#include <string>
#include <vector>
#include "Player.h"
#include "Midfielder.h"
#include "TeamManagement.h"
using namespace std;
TeamManagement::TeamManagement()
{
}
std::vector<Player> midfielder(8);
//errors start occurring on line below: 'midfielder' does not name a type
midfielder.at(0) = Midfielder("Default         ",0,"Midfielder");
midfielder.at(1) = Midfielder("David Armitage  ",1,"Midfielder");
midfielder.at(2) = Midfielder("Tom Rockliff    ",2,"Midfielder");
midfielder.at(3) = Midfielder("Gary Ablett     ",3,"Midfielder");
midfielder.at(4) = Midfielder("Dyson Heppel    ",4,"Midfielder");
midfielder.at(5) = Midfielder("Scott Pendlebury",5,"Midfielder");
midfielder.at(6) = Midfielder("Michael Barlow  ",6,"Midfielder");
midfielder.at(7) = Midfielder("Jack Steven     ",7,"Midfielder");
//errors stop occurring here
void TeamManagement::Display_Players(){
cout<<"Position     Name              ID"<<endl;
for (int i=1;i<8;i++)
    {
         cout<<midfielder[i].Player_Details()<<"   "<<midfielder[i].Get_player_id()<<endl;
    }
}

第一个问题是不能在函数外部执行这样的赋值。必须使用构造或初始化。

在c++ 98中,不能在函数之外填充/初始化vector。

在c++ 11/14中,你可以使用初始化语法填充一个:

#include <iostream>
#include <vector>
struct Thing {
    int m_i, m_j;
    Thing(int i, int j) : m_i(i), m_j(j) {}
};
std::vector<Thing> things {
    { 1, 2 }, { 2, 3 }
};
int main() {
    std::cout << "things[0].m_j = " << things[0].m_j << 'n';
}

但是std::vector不会喜欢你试图将"中场"放入Player的vector中。让我们使用SSCCE来重建您正在做的损坏:

#include <iostream>
struct Base {
    int i;
};
struct Derived : public Base {
    int j;
};
int main() {
    std::cout << "Base size = " << sizeof(Base) << 'n';
    std::cout << "Derived size = " << sizeof(Derived) << 'n';
}

这告诉我们Base和Derived有不同的大小。但是你试着把这两个物体放在同一个容器里因为它们是相关的。圆钉和方钉是相关的……它们不能装进同一个洞,这就是我们现在的问题。

vector根据你提供的类型在内存中为元素创建空间,然后要求你传递给它用来填充这些空间的类型,或者传递给它具有到存储类型转换机制的类型。

如果你想拥有不同类型的容器,你就需要使用指针,但这样你就会遇到这样的问题:你返回的将是一个指向基本类型的指针,你需要为自己提供一种区分不同玩家类型的方法。

参见在基类变量中存储派生类对象的c++ 98方法。在现代c++(11和14)中,你应该使用智能指针,例如

std::vector<std::unique_ptr<Base>>
std::vector<std::shared_ptr<Base>>

假设默认构造一个Midfielder没有多大意义,所以可以将reserve放入内存,然后将emplace_back放入vector

std::vector<Player> midfielder {};
midfielder.reserve(8);
midfielder.emplace_back("Default         ",0,"Midfielder");
midfielder.emplace_back("David Armitage  ",1,"Midfielder");
midfielder.emplace_back("Tom Rockliff    ",2,"Midfielder");
midfielder.emplace_back("Gary Ablett     ",3,"Midfielder");
midfielder.emplace_back("Dyson Heppel    ",4,"Midfielder");
midfielder.emplace_back("Scott Pendlebury",5,"Midfielder");
midfielder.emplace_back("Michael Barlow  ",6,"Midfielder");
midfielder.emplace_back("Jack Steven     ",7,"Midfielder");

midfielder.at(0) = Midfielder("Default ",0,"Midfielder");是一个语句。您已经将该语句和类似语句放在(全局)名称空间作用域中。那是你的毛病。只有声明可以在命名空间范围内。你必须把你的语句放在函数中。

错误消息源于这样一个事实,即不以关键字开头的声明以类型名称开头。由于midfielder不是关键字,编译器期望它是一个类型名,但它不是,所以你得到了错误。