【问题标题】:C++ Struct invalid use of non-static data memberC++ Struct 无效使用非静态数据成员
【发布时间】:2013-10-14 22:07:08
【问题描述】:

我收到有关非静态成员的无效使用以及结构成员无法正常工作的其他问题的错误,我无法理解问题是什么,谢谢。

#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;
                  ^

【问题讨论】:

  • 我倾向于给类型和实例不同的名称以避免混淆。例如。 struct ClassRoomclassroom。话虽如此,您需要检查名称查找规则以查看编译器是否正确认为 main 中的 classroom 指的是类型。
  • 正如 tristan 所说,您应该使用 const 大小的数组或一些标准容器,如向量或列表

标签: c++ arrays struct


【解决方案1】:

您不能声明数组int ListOfStudents[NumberOfStudents],除非NumberOfStudents 的类型为const int。如果它是变量(即不是const),那么编译器不知道如何为您的数组分配空间。所以只需将int NumberOfStudents; 更改为const int NumberOfStudents;。但是,当您这样做时,您的结构也将期望 NumberOfStudents 是静态的,因此您实际上需要编写 static const int NumberOfStudents;

此时,您将无法cin &gt;&gt; classroom.NumberOfStudents,事情变得非常丑陋。我假设这不是你想要做的。

如果您确实想要一个可变大小的数组,那么执行此操作的标准方法是使用堆分配。换句话说,您需要将ListOfStudents 声明为指向整数数组的指针,您将在运行时分配该数组。

也就是说,你想改变你的结构如下:

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

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

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

最后一点:这样做,您还需要将您的cin &gt;&gt; classroom.ListOfStudents; 更改为一个循环,该循环会将所有值读入您的数组。像这样:

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

正如其他答案所建议的那样,更改变量的名称 classroom 也是一个好主意,因此它与结构的名称不匹配。但是它仍然应该编译得很好(我测试过)。只是有点混乱。

【讨论】:

  • 或者只使用 std::vector
  • 使用 std::vector 即使数组不应该为每个结构实例改变?
【解决方案2】:

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

编辑:

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

此错误表示没有与类型 &int 匹配的运算符>>。您可能想要循环并打印数组的每个元素。

【讨论】:

    【解决方案3】:

    你可以这样做,通过在你的函数中创建一个局部变量(因为虽然不推荐使用全局变量):

    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;
    }
    

    【讨论】:

    • 有一个全局变量,名称为教室
    • 代码应该在不更改实例名称的情况下编译。问题是数组。
    【解决方案4】:

    你不能有一个与结构同名的变量,把结构底部的“教室”改成别的东西。或者将结构设为“教室”。

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

    你也可以在 main 中创建一个 struct 类型的变量:

    classroom someClassroom;
    

    【讨论】:

    • 这不是问题。用实例名来掩盖类名并不是一个好主意,但代码应该可以编译。问题确实是 VLA。
    猜你喜欢
    • 1970-01-01
    • 2016-01-12
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 2017-09-12
    相关资源
    最近更新 更多