0

I'm trying to have three private data members (string firstName[], string lastName[], and float testScores[]) in a class where the number of elements is an input from a public data member, totalStudents (which is user defined). Further, adding const in front of totalStudents isn't an option because the value changes when the user inputs the value. Here is the header code (C++):

#ifndef __newClassHeader.h__
#define __newClassHeader.h__
#include <iostream>
#include <string>
using namespace std;

class student {
    public:
        student();
        int totalStudents;
        int askStud() {
            cout << "Enter the number of students: ";
            cin >> totalStudents;
        }
        

    private:
        string FirstName[totalStudents]; // error: a nonstatic member reference must be relative to a specific object
        string lastName[totalStudents];  // error: a nonstatic member reference must be relative to a specific object
};

#endif

I tried adding a totalStudentsPtr variable (that points to totalStudents) after the user info, but that spit out the same issue. For example, I tried this

#ifndef __newClassHeader.h__
#define __newClassHeader.h__
#include <iostream>
#include <string>
using namespace std;

class student {
    public:
        student();
        int totalStudents;
        int askStud() {
            cout << "Enter the number of students: ";
            cin >> totalStudents;
        }
        string firstName[totalStudents]; // error– a nonstatic member reference must be relative to a specific object
        string LastName[totalStudents];  // error– a nonstatic member reference must be relative to a specific object
        

    private:
        string* FirstName;
        string* lastName;
};

#endif

but it gives the same error code. Also, I tried using protected instead of private, but that also didn't work.

  • 4
    ... Why not just `string firstName` and `string lastName`? Why does a single `student` object need to have an entire array of strings of names of other students? – Nathan Pierson Nov 06 '22 at 20:06
  • Unrelated to question: Neither dots nor double underscores are allowed in the header guard. The former should give you a warning from the compiler that everything starting with the dot will be ignored and the latter can have very unexpected effects because all identifiers with double underscore are reserved for the compiler and standard library. – user17732522 Nov 06 '22 at 20:09
  • And assuming that you have a good reasons that these are arrays of strings instead of just single strings, you should use `std::vector` for a dynamically-sized number of `std::string` objects, not arrays. (All of this has nothing to do with the `private` part by the way. The problem is that the size of an array must be a compile-time constant, which `totalStudents` isn't.) – user17732522 Nov 06 '22 at 20:14
  • I used dots and underlines in other header files, and those programs worked fine. I'm using vectors, and so far, so good. I haven't tested the program yet as of writing this, but I'm not getting any errors with my program. Fingers crossed! – this.user.man Nov 07 '22 at 02:07
  • @nathan The firstName and lastName variables are supposed to hold the first names and last names of students that the user enters. I know how to go from there, but I'm unsure how to eliminate this error if that makes sense. – this.user.man Nov 07 '22 at 02:14
  • My suggestion would be that each `student` should only know about the details for a single `student`'s worth of information, and then you can have a `std::vector` that contains multiple entire `student` objects. – Nathan Pierson Nov 07 '22 at 04:12

1 Answers1

0

When you declare an array field as string firstName[totalStudents]; you are telling the compiler to allocate static (read stack) memory for an array with a number of elements that is not yet known (also dynamic). This is not how the compiler works.

You need to either use a value that is constant at compile time, or use std::vector:

class student {
    
    public:
        student();
        int askStud() {
            cout << "Enter the number of students: ";
            cin >> totalStudents;
        }
        

    private:
        vector<string> FirstName; // Dynamically sized!
        vector<string> lastName;  // Dynamically sized!
};

P.S. Try to avoid using using namespace std; in header files as it pollutes the global namespace.

Sup3rlum
  • 121
  • 4
  • A `std::vector` is a good container to use if what you're trying to do is store a dynamically-sized collection of homogenously-typed elements. But it's far from obvious that it makes any sense to do this in the first place for a `student` object. Changing code from nonsense that doesn't compile to nonsense that happens to compile is a pretty small improvement. – Nathan Pierson Nov 06 '22 at 20:26
  • Sure, however it doesn't really help that there is practically no context given. Yes, it doesn't make sense whatsover, but if you go into the rabbit whole of figuring what OP is trying to actually do, you will just end up doing their homeowork for them. – Sup3rlum Nov 06 '22 at 20:45
  • I’m trying to keep the question short and concise because I’m having an issue with that part. I spent time looking at other forums and websites for that. I’m obviously not very good at explaining the question plus I haven’t been doing this for a long time. Cut me some slack :/ – this.user.man Nov 07 '22 at 00:50