【问题标题】:How do i make an array which is a class object and has a compile time size?我如何制作一个作为类对象并具有编译时大小的数组?
【发布时间】:2020-04-21 00:54:20
【问题描述】:

我是这方面的新手,并没有做太多,但我真的坚持制作一个编译时大小的数组,它是一个类对象。也许有一种方法可以保存文件中的所有信息,同时占用更少的内存?这是我的一些代码:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

class Beer
{
public:
    string name;
    string rating;
    string country;
    string alc;
    string type;
};

int main()   //Function uses ''bytes of stack/exceeds analyze:stacksize '16384'. 
             //Consider moving some data to heap
{
    ifstream file("beer.txt");

    if (!file.good())
    {
        cout << "Error. File was not found." << endl;
        exit(EXIT_FAILURE);
    }
    else
    {
        int count;
        string line;
        ifstream file("beer.txt");
        int count = 0;
        for (int i = 0; !file.eof(); i++)
        {
            getline(file, line);
            count++;
        }

        const int SIZE = count;  //<- this is the place i'm struggling with

        Beer allBeers[SIZE];     //expression must have a constant value
        Beer currentBeer;  

        for (int i = 0; !file.eof(); i++)
        {
            getline(file, currentBeer.name, '\t');
            getline(file, currentBeer.rating, '\t');
            getline(file, currentBeer.country, '\t');
            getline(file, currentBeer.alc, '\t');
            getline(file, currentBeer.type, '\n');

            allBeers[i] = currentBeer;
        }


    }
    file.close();
    return 0;
}

【问题讨论】:

  • 为什么你想要一个编译时数组?特别是因为您在编译时没有信息。您正在运行时从文件中读取它们。
  • 那么大的就是多余的
  • 请定义限制(总是)。 IE。允许的最小输入大小和最大输入大小是多少。 beers.txt 的最大长度是多少——1GB?更多的?突然之间,基于堆栈的数组变得不是一个好主意。
  • 当学习从一些现实生活的需求开始。例如数据库之类的需求。 IE。 “显示所有等级为 5 且国家/地区为‘英国’的熊”。
  • 我的意思显然是“啤酒”而不是“熊”......干杯:)

标签: c++ arrays class memory compile-time


【解决方案1】:

如果您在编译时不知道大小,那么您应该改用std::vector

https://en.cppreference.com/w/cpp/container/vector

#include &lt;vector&gt;

然后

std::vector<Beer> allBeers;

稍后,添加啤酒:

allBeers.push_back(currentBeer);

【讨论】:

  • 谢谢!!矢量是我一直缺少的 :))
【解决方案2】:

如果您在编译时不知道数组的大小,只需使用std::vector

#include <vector>

// ...

// const int SIZE = count;  // you don't need this anymore
std::vector<Beer> allBeers;     

// ...

allBeers.push_back(currentBeer); // to append it to your 'array'

vectors 的行为与数组非常相似,但是当使用push_back 时,它们会在需要时“增长”。请注意,它们可能会保留比必要更多的内存,因此它们不必在每次调用 push_back 时都增加。要释放此保留的内存,您可以在之后调用一次shrink_to_fit

如果您不想使用shrink_to_fit,您也可以预先将vector 精确设置为您需要的大小

const int SIZE = count;
std::vector<Beer> allBeers;  
allBeers.reserve(SIZE);

【讨论】:

  • 当我使用向量时,我得到的错误是 'std::vector':'Beer' is not a valid template type argument for parameter '_Ty'
【解决方案3】:

您的代码的主要问题在于以下两行:

    const int SIZE = count;  //<- this is the place i'm struggling with
    Beer allBeers[SIZE];     //expression must have a constant value

现在,虽然SIZE 被定义为const,但它不是 编译时 常量!此外,C++ 中的数组需要 编译时 常量的维度。 (您的const 限定符仅表示,一旦初始化,SIZE 的值就无法更改。)

解决此问题的简单“老式 C++”方法是将 allBeers 声明为 指针 并使用 new 运算符在运行时创建“数组缓冲区” -time(当SIZE实际值已知时):

    const int SIZE = count;  // Don't really need this, now - could just use "count"
    Beer* allBeers = new Beer[SIZE]; // You can still use allBeers[i] to access!

但是,在这里,您应该确保在完成数组/缓冲区后执行delete[] allBeers;

一种更现代的方法是使用std::vector 类型,在这种情况下,当对象超出范围时释放内存会自行处理:

    const size_t SIZE = size_t(count);
    std::vector<Beer> allBeers(SIZE);

同样,您可以使用 allBeers[i] 访问。

请随时要求进一步澄清和/或解释。

【讨论】:

  • PS:“啤酒”和“记忆”这两个词很少一起使用! ? ‎
  • 哈哈,如果你把大脑放在他们之间 :D 谢谢你的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 2013-12-23
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多