繁体   English   中英

C++ 指向对象的指针堆数组,如何将字符串传递给特定的 object? 有一些代码请看一下:

[英]C++ Heap array of pointers to objects, how can I pass a string to a specific object? Have some code please take a look:

我怎样才能简单地将这行文本传递给成员 function? 这就是我要问的...有一个名为 Student:Populate(std::string) 的成员 function 我想将 Student 的特定实例连接到特定文件行的数据...我不知道如何在语法上做到这一点。

这是为了学校作业,所以我必须使用手动分配新/删除,没有智能指针和向量,所以只需排除这些。

int main(){
std::stringstream stream;
std::string current;
Student temp;
Student *database = new Student[50];

inFile.open("students.dat", std::ifstream::in);
outFile.open("FullReport.txt",std::ofstream::out);

while(getline(inFile,current)){
   for(int i = 0; i < 50; i++){
        Student[i] = new Student(current); //this line doesn't work when it's compiled

        outFile << Student[i] <<std::endl; //neither does this one

       //there is a Student Populate(std::string); function I would like to pass the data to... How can I do that? 

   }
   inFile.close();
   outFile.close();
}

编译器错误:

错误:'[' token Student[i] = new Student(current); 之前的预期 unqualified-id; ^ main.cpp:26:27: 错误: '[' token outFile << Student[i] < 之前的预期主表达式

所以,有几件事。

首先,没有Student[i] Student是 class 名称。 类没有办法从operator[]访问,除非你重载它(可能是你类中的未来主题),即使那样它也可能不会是 static,这意味着Student[i]没有真正的意义。

但是,有一个database[i] ,这可能是您想要的。

其次, database[i]不是指针,因此没有理由使用new进行分配。 您已经在上面使用Student *database = new Student[50]; ,所以即使是类似database[i] = new Student(current); 是没有意义的。 相反,试试这个:

database[i] = Student(current);

这会将Student的新实例分配给database[i] 这里不需要new的。

最后,请注意,这会将Student实例分配给database[i] ,这意味着它将调用构造函数。 如果您没有接受std::string的构造函数,则不会编译。 它也不会调用Populate()

如果你想调用Student::Populate() ,你需要在 object 的实例上调用它。 像这样:

database[i].Populate(current);

我希望这就是你要问的。


PS我还应该提到,作为一般规则,你不应该使用new 标准模板库要好得多。

当然,大多数学校作业不允许这样做,所以有时你必须使用new 但我想我还是应该提一下。

让 go 一点一点地思考这个

int main()
{   
    std::stringstream stream;

stream在这里没有使用。 现在让我们摆脱它。 不过,它稍后会再次出现。

    std::string current;
    Student temp;
    Student *database = new Student[50];

这将创建 50 个Student

    inFile.open("students.dat", std::ifstream::in);
    outFile.open("FullReport.txt",std::ofstream::out);

打开文件。 可以做得更好一点,但正确。

    while(getline(inFile,current))
    {   

完美的。 从文件中得到一行。

        for(int i = 0; i < 50; i++)

使用文件中的这一行,做同样的事情 50 次。 问问你的橡皮鸭,它是否认为这是有道理的。

        {   
            Student[i] = new Student(current);

Student是一种类型,而不是变量。 你不能存储在一个类型中。 您可能打算使用database ,但它是Student的数组,并且new Student(current)提供指向Student的指针。

            outFile << Student[i] <<std::endl;
        }
        inFile.close();
        outFile.close();

过早关闭文件。 你还没有读完所有的学生。

    }
}

怎么修:

int main()
{
    std::string current;
    Student **database = new Student*[50];

database是一个包含 50 个指向Student的指针的数组,已经准备好接受new Student 但稍后会详细介绍。

    std::ifstream inFile("students.dat");
    std::ofstream outFile("FullReport.txt");

如果我们在这里定义文件流并指定方向( ifstreamofstream ),我们不需要再次指定它。 另外,我们可以直接在构造函数中打开文件。 谁需要凌乱的电话才能open 最后,因为文件是局部变量,它们将在 function 结束时自动销毁并关闭。 不需要一个凌乱的电话来close (有关此概念的更多信息,请参阅资源获取是初始化 (RAII) 的含义? )您不必编写的代码没有错误。 如果它以某种方式发生,他们不是你的错。

    int count = 0;

count是一个比 i 更具描述性的名称

    while (std::getline(inFile, current))
    {

这里没有任何改变。 这是太棒了。 Stack Overflow 上有一个著名的问题,因为有多少人犯了这个错误。 荣誉。 你答对了。

        database[count] = new Student(current);

Student分配并添加到数据库。 稍后再谈。

        outFile << *database[count] << std::endl;

并写入 output 文件。 注意*取消引用指针并获取指向的值,以便可以使用常规<<运算符(顺便说一下,您必须提供)打印它。 没有*程序将打印出指针的内容:地址。

        count++;
    }
}

再一次没有所有的解释,以便于阅读代码

int main()
{
    std::string current;
    Student **database = new Student*[50];

    std::ifstream inFile("students.dat");
    std::ofstream outFile("FullReport.txt");

    int count = 0;

    while (std::getline(inFile, current))
    {

        database[count] = new Student(current);

        outFile << *database[count] << std::endl;

        count++;
    }
}

好的,以后再说。 你不想

Student **database = new Student*[50];

这很恶心,有几个原因。

  1. 现代计算机非常擅长直线思考。 如果数据在一条漂亮的直线上,他们可以提前阅读并在您需要之前为您准备好数据。 Arrays 的数据很棒。 Arrays 指向数据的指针会阻止计算机启动速度。 它读取一个Student ,然后它必须查找另一个指针才能找到下一个Student 这可能很慢。 慢得令人发指。 在使用Student 0 时使用Student数组,计算机正在加载(或在加载Student 0 时已经加载)下一组Student
  2. 每个动态分配都有成本。 程序必须向操作系统请求一块 memory。 操作系统必须找到一个。 这可能很昂贵。 最好得到一大块 memory 并将其分成一组Student
  3. 每个动态分配都必须放弃。 分配 50 个Student ,您需要有存放 50 个Student的代码。 分配一个Student数组,你就收起了一个Students数组

你想要更多类似的东西

int main()
{
    std::string current;
    Student *database = new Student[50];

    std::ifstream inFile("students.dat");
    std::ofstream outFile("FullReport.txt");

    int count = 0;

    while (std::getline(inFile, current))
    {
        database[count] = Student(current);
        outFile << *database[count] << std::endl;
        count++;
    }
}

当然你真正想要的是

int main()
{
    std::string current;
    std::vector<Student> database;

    std::ifstream inFile("students.dat");
    std::ofstream outFile("FullReport.txt");

    while (std::getline(inFile, current))
    {
        database.emplace_back(current);
        outFile << database.back() << std::endl;
        count++;
    }
}

但这将从教练那里得到一个不错的零回合。 学校的第一条规则是给老师他们想要的东西并通过课程。 第二条规则是阅读一堆其他的东西来学习你没有被教过的东西,这样你毕业后就不会无用了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM