【问题标题】:Filing a vector outside of a function in a class在类中的函数之外归档向量
【发布时间】:2015-08-09 09:58:00
【问题描述】:

这里有一个相当简单的问题,在类 .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");

为了提供上下文,“Midfielder”是一个继承自“Player”类的类。

团队管理.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

团队管理.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;
    }
}

【问题讨论】:

  • 请注意,将Midfielder 添加到vector&lt;Player&gt; 将涉及object slicing
  • "which is not working" 你必须比这更具体。你期望什么输出?你得到了什么?程序崩溃了吗?在哪条线上?它不编译吗?信息是什么?不要让我们猜测。
  • 哦,对不起,我才刚刚加入该网站。当我编译我得到错误'midfielder'没有命名类型
  • @JacksonFrisby-Smith 将相关信息放入您的问题中。并说明是哪一行导致了错误。
  • 错误:'midfielder' 没有命名类型,对于我在向量中填充一个点的每一行,例如 midfielder.at(0) = Midfielder("Default ",0,"Midfielder" );对于 8 次出现的每一次,我都会得到这个。我已经编辑了问题并添加了相关类的 .h 和 .cpp 文件,因此希望这可以更清楚地说明我的错误。感谢您的帮助!

标签: c++ oop object vector


【解决方案1】:

大概默认构造一个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");

【讨论】:

  • 这更有意义,谢谢!但是我仍然没有在此范围内声明“中场”。我应该在课堂的什么地方使用这段代码?
【解决方案2】:

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

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

【讨论】:

  • 这更像是一个编译错误而不是一个错误 - 该错误将发生在 cmets 中提到的对象切片中。
  • @doctorlove 我认为这是一个语法错误。错误的定义多种多样。是的,这不是代码中唯一的错误。
【解决方案3】:

第一个问题是你不能像在函数之外那样执行赋值。您必须使用构造或初始化。

使用 C++98,您无法在函数之外填充/初始化向量。

使用 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 的向量中。让我们使用 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 的大小不同。但是您试图将这两个对象放入同一个容器中,因为它们是相关的。圆钉和方钉是相关的……它们不适合同一个洞,这就是我们现在遇到的问题。

向量会根据您提供的类型在内存中为您的元素创建空间,然后它要求您将准确的类型传递给它以填充这些空间,或者具有到存储类型的转换机制的类型。

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

有关 C++98 方法,请参阅 Store derived class objects in base class variables。在现代 C++(11 和 14)中,您应该使用智能指针,例如

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

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

【讨论】:

  • 我想我可以将向量更改为“中场”而不是“球员”,并为每个位置创建单独的向量。我将如何初始化向量,以便我可以在整个类的函数中使用它的元素?
猜你喜欢
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 2018-12-14
  • 2019-12-12
  • 2020-12-13
  • 1970-01-01
相关资源
最近更新 更多