Проблемы с инициализацией и увеличением статической переменной-члена

Я новичок в С++, и у меня возникают проблемы с моим кодом здесь:

#include <iostream>

using namespace std;

class Student {
  public:
    string student_name;
    double CGPA;
    string degree;
    static unsigned int count_total_no_of_students_enrolled; //STATIC VARIABLE
    const string uni_name = "umt";
    
    void setstudent(string a, double b, string c);
    void displaystudent();
    void display_total_no_of_student();

};

void Student::setstudent(string a, double b, string c) {
   student_name = a;
   CGPA = b;
   degree = c;

   count_total_no_of_students_enrolled++; //******THIS ISN'T WORKING******
}

void Student::displaystudent() {
   cout << "\n=> Student details:\n";
   cout << "   Name: "<< student_name << ",CGPA: " << CGPA << "\n   Degree: " << degree << ",University: " << uni_name;
}

void Student::display_total_no_of_student() {
   cout << "\n Total Students Enrolled: " << count_total_no_of_students_enrolled;
 }

int main() {

   Student s1, s2, s3;

   s1.setstudent("John Doe", 3.5 , "CS");
   s2.setstudent("Jane Doe", 3.9 , "CS");
   s3.setstudent("Jim Doe", 3.8, "CA");

   s1.displaystudent(); s2.displaystudent(); s3.displaystudent();
 
  display_total_no_of_student(); //*****THIS GIVES ERROR TOO*****

  return 0;
}

Все работает, как и ожидалось, за исключением переменной static. Я хочу увеличивать его значение на 1 каждый раз, когда создается новый объект класса Student. Любая помощь, которую вы оказываете, будет принята с благодарностью

Почему в Python есть оператор &quot;pass&quot;?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
0
775
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Статические переменные должны быть инициализированы. Инициализируйте статическую переменную вне объявления.

Объявление статического члена данных в определении его класса не является определением и может иметь неполный тип, отличный от void с указанием cv. Определение статического члена данных должно появиться в области пространства имен, включающей определение класса члена. В определении области пространства имен имя члена статических данных должно уточняться именем его класса с использованием оператора ::. Выражение инициализатора в определении статического члена данных находится в области действия его класса (3.3.7).

Ответ принят как подходящий

Две ошибки в вашем коде:

  1. Ваш вызов display_total_no_of_student() не предоставляет ни объект класса, ни имя класса для этой функции, поэтому компилятор ищет «свободную» функцию с таким именем/сигнатурой, которую он не находит.

  2. Хотя вы предоставили объявление для статического члена count_total_no_of_students_enrolled, вы не дали для него фактического определения (что должно быть сделано вне определения класса).

Для первой проблемы вы, скорее всего, захотите объявить display_total_no_of_student как static функцию (поскольку она не использует и не требует какого-либо конкретного экземпляра класса Student). Для второй проблемы просто предоставьте определение члена count_total_no_of_students_enrolled, который должен быть инициализирован нулем.

Вот «рабочая» версия вашего кода, в которой устранены следующие проблемы:

#include <iostream>

using namespace std;

class Student {
public:
    string student_name;
    double CGPA;
    string degree;
    static unsigned int count_total_no_of_students_enrolled; // This DECLARES the variable but doesn't define it!
    const string uni_name = "umt";

    void setstudent(string a, double b, string c);
    void displaystudent();
    static void display_total_no_of_student(); // Declare this function as static!
};

unsigned int Student::count_total_no_of_students_enrolled = 0; // This is the REQUIRED definition and initial value!

void Student::setstudent(string a, double b, string c)
{
    student_name = a;
    CGPA = b;
    degree = c;

    count_total_no_of_students_enrolled++; //******THIS ISN'T WORKING******
}

void Student::displaystudent()
{
    cout << "\n=> Student details:\n";
    cout << "   Name: " << student_name << ",CGPA: " << CGPA << "\n   Degree: " << degree << ",University: " << uni_name;
}

void Student::display_total_no_of_student()
{
    cout << "\n Total Students Enrolled: " << count_total_no_of_students_enrolled;
}

int main()
{
    Student s1, s2, s3;

    s1.setstudent("John Doe", 3.5, "CS");
    s2.setstudent("Jane Doe", 3.9, "CS");
    s3.setstudent("Jim Doe", 3.8, "CA");

    s1.displaystudent(); s2.displaystudent(); s3.displaystudent();

    Student::display_total_no_of_student(); // Specify the class name to access a static member function!

    return 0;
}

Пожалуйста, не стесняйтесь обращаться за любыми дополнительными разъяснениями и/или пояснениями.

Дэн! Спасибо чувак. Вы мне все ясно объяснили :)

RAZ0229 20.12.2020 17:45

Чтобы расширить ответ Адриана относительно static:

Вы только объявляете static переменную count_total_no_of_students_enrolled внутри класса — вам нужно предоставить соответствующее определение. Здесь у вас есть два варианта: либо указать определение перед main следующим образом:

    unsigned int Student::count_total_no_of_students_enrolled = 0;

Или рассмотрите возможность использования встроенных переменных C++ 17:

    class Student {
    static inline unsigned int count_total_no_of_students_enrolled = 0;
    //...
    }

До C++17 единственным доступным вариантом был первый. Это произошло потому, что объявление class на самом деле не выделяет память: это объявление. Однако ваши переменные static существуют независимо от объектов вашего класса, поэтому вам нужно было предоставить для них единственное определение где-то снаружи, чтобы компилятор мог выделить память. Переменные inline C++17 делают это немного более эргономичным.

Другие вопросы по теме