C++结构体中非静态数据成员的无效使用

4
我遇到了有关非静态成员无效使用的错误以及来自结构体成员未正常工作的其他问题,我很难理解问题所在,谢谢。
#include <iostream>
#include <string>
using namespace std;


struct classroom {
int RoomNumber;
int NumberOfChairs;
int NumberOfStudents;
int ListOfStudents[NumberOfStudents];
string LectureName;
bool Window, Projector, Available;
}classroom;




int main() {

cout << "Please enter your room number" << endl;
cin >> classroom.RoomNumber;
cout << "Enter the name of the Lecture" << endl;
cin >> classroom.LectureName;
cout << "Enter  number of students" << endl;
cin >> classroom.NumberOfStudents;
cout << "Enter " << classroom.NumberOfStudents <<  " Student Names" << endl;
cin >> classroom.ListOfStudents;
cout << "Enter number of chairs" << endl;
cin >> classroom.NumberOfChairs;
cout << "Are there any Windows? (Y/N)" << endl;
cin >> classroom.Window;
cout << "Are there any Projectors? (Y/N)" << endl;
cin >> classroom.Projector;
cout << "Are there any Available? (Y/N)" << endl;
cin >> classroom.Available;

    return 0;
}

错误

prog.cpp:10:5: error: invalid use of non-static data member ‘classroom::NumberOfStudents’
 int NumberOfStudents;
     ^
prog.cpp:11:20: error: from this location
 int ListOfStudents[NumberOfStudents];
                    ^
prog.cpp: In function ‘int main()’:
prog.cpp:28:18: error: ‘struct classroom’ has no member named ‘ListOfStudents’
 cin >> classroom.ListOfStudents;
                  ^

1
我倾向于给类型和实例不同的名称以避免混淆,例如 struct ClassRoomclassroom。话虽如此,您需要检查名称查找规则,以确定编译器是否正确地将 main 中的 classroom 视为类型。 - Keith
正如Tristan所说,您应该选择具有常量大小的数组或某些标准容器(如向量或列表)。 - sajas
4个回答

11
如果变量 NumberOfStudents 不是 const int 类型,你就不能声明数组 int ListOfStudents [NumberOfStudents]。编译器不知道为数组分配多大的空间。因此,只需将 int NumberOfStudents; 改为 const int NumberOfStudents;。但是这样做后,结构体也需要预期 NumberOfStudents 为静态,并且您实际上需要编写 static const int NumberOfStudents;
此时,您就无法使用 cin >> classroom.NumberOfStudents 语句进行输入。事情会变得非常棘手。我想这不是你想做的事情。
如果你确实想要一个大小可变的数组,则标准方法是使用堆分配。换句话说,您需要将 ListOfStudents 声明为指向整数数组的指针,并在运行时分配它。
也就是说,您需要按如下方式更改结构体:
struct classroom {
int RoomNumber;
int NumberOfChairs;
int NumberOfStudents;
int* ListOfStudents;
string LectureName;
bool Window, Projector, Available;
}classroom;

然后在你的main函数(或你喜欢的任何地方),你需要调用new来分配一些空间。像这样:

那么在你的main函数(或者实际上是任何你喜欢的地方),你需要调用new来分配一些空间。像这样:

classroom.ListOfStudents = new int[classroom.NumberOfStudents];

最后一点提示:在这里,您还需要将cin >> classroom.ListOfStudents;更改为一个循环,以便将所有值读入数组中。像这样:

for(int i=0; i<sizeOfArray; i++) {
    cin >> classroom.ListOfStudents[i];
}
for (int i=0; i < classroom.NumberOfStudents; i++) {
  cin >> classroom.ListOfStudents[i];
}

正如其他回答所建议的那样,更改您的变量classroom的名称,以便它不匹配结构体的名称,这也是一个好主意。但是,它应该仍然可以正常编译(我已经测试过了)。只是有点令人困惑。


2
或者直接使用std::vector。 - OMGtechy
即使结构体的每个实例不打算更改,也应使用std::vector吗? - kotoko

4

C++不支持可变长度数组(VLA),因此您不应使用ListOfStudents [NumberOfStudents]。使用const代替。

编辑:

prog.cpp:28:18: error: ‘struct classroom’ has no member named ‘ListOfStudents’
 cin >> classroom.ListOfStudents;

这个错误表示没有匹配类型&int的operator>>。您可能需要循环并打印数组中的每个元素。


1
你可以通过在函数中创建一个本地变量来实现这一点(因为不建议使用全局变量):
struct classroom {
    int RoomNumber;
    int NumberOfChairs;
    int NumberOfStudents;
    int ListOfStudents[NumberOfStudents];
    string LectureName;
    bool Window, Projector, Available;
};

int main(){
    classroom myClassRoom;

    cout << "Please enter your room number" << endl;
    cin >> myClassRoom.RoomNumber;
    cout << "Enter the name of the Lecture" << endl;
    cin >> myClassRoom.LectureName;
    cout << "Enter  number of students" << endl;
    cin >> myClassRoom.NumberOfStudents;
    cout << "Enter " << myClassRoom.NumberOfStudents <<  " Student Names" << endl;
    cin >> myClassRoom.ListOfStudents;
    cout << "Enter number of chairs" << endl;
    cin >> myClassRoom.NumberOfChairs;
    cout << "Are there any Windows? (Y/N)" << endl;
    cin >> myClassRoom.Window;
    cout << "Are there any Projectors? (Y/N)" << endl;
    cin >> myClassRoom.Projector;
    cout << "Are there any Available? (Y/N)" << endl;
    cin >> myClassRoom.Available;

    return 0;
}

或者如果你想要全局变量,就改变它的名称,让编译器区分结构体和变量名称,然后在你的main()函数中使用myClassRoom代替classroom

struct classroom {
    int RoomNumber;
    int NumberOfChairs;
    int NumberOfStudents;
    int ListOfStudents[NumberOfStudents];
    string LectureName;
    bool Window, Projector, Available;
}myClassRoom;
编辑:您需要将ListOfStudents的长度设置为固定数字,例如
int ListOfStudents[512];

然后,这段代码在我的VS中编译通过:
struct classroom {
    int RoomNumber;
    int NumberOfChairs;
        int NumberOfStudents;
    int ListOfStudents[200];
    string LectureName;
    bool Window, Projector, Available;
};

int main(){
    classroom myClassRoom;

    cout << "Please enter your room number" << endl;
    cin >> myClassRoom.RoomNumber;
    cout << "Enter the name of the Lecture" << endl;
    cin >> myClassRoom.LectureName;
    cout << "Enter  number of students" << endl;
    cin >> myClassRoom.NumberOfStudents;
    cout << "Enter " << myClassRoom.NumberOfStudents <<  " Student Names" << endl;
    for(int i = 0; i < myClassRoom.NumberOfStudents; ++i)
    {
        cin >> myClassRoom.ListOfStudents[i];
    }
    cout << "Enter number of chairs" << endl;
    cin >> myClassRoom.NumberOfChairs;
    cout << "Are there any Windows? (Y/N)" << endl;
    cin >> myClassRoom.Window;
    cout << "Are there any Projectors? (Y/N)" << endl;
    cin >> myClassRoom.Projector;
    cout << "Are there any Available? (Y/N)" << endl;
    cin >> myClassRoom.Available;

    return 0;
}

有一个名为“classroom”的全局变量。 - tristan
代码应该在不更改实例名称的情况下编译。问题出在数组上。 - juanchopanza

0

你不能使用与结构体同名的变量,将结构体底部的"classroom"更改为其他名称。或者将结构体命名为"Classroom"。

struct Classroom {
    int RoomNumber;
    int NumberOfChairs;
    int NumberOfStudents;
    int ListOfStudents[NumberOfStudents];
    string LectureName;
    bool Window, Projector, Available;
}somethingelse;

你也可以在main函数中使用以下代码定义一个结构体类型的变量:
classroom someClassroom;

2
这不是问题所在。实例名称掩盖类名并不是一个好主意,但代码应该可以编译。真正的问题是VLA。 - juanchopanza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接