Как создать счетчик для каждого объекта класса?
В коде есть класс School с полем quantity_of_pupils, которое далее будет увеличиваться на, +1 т.к. в школе прибавляется ученик. Класс Pupil наследуется из предыдущего и при создании объекта должен увеличиваться счетчик quantity_of_pupils у соответствующей школы, но при вызове print_quantity выводятся нули у обеих школ.
#include <iostream>
#include <string>
using namespace std;
class School
{
protected:
string name_of_school;
unsigned quantity_of_pupils{0};
public:
School(string name_of_school): name_of_school(name_of_school){}
void print()
{
cout << "school name: " << name_of_school << " ";
}
void print_quantity()
{
cout << "quantity of pupils: " << quantity_of_pupils << '\n';
}
};
class Pupil : public School
{
private:
string name;
unsigned age;
public:
Pupil(School name_of_school ,string name, unsigned age): School(name_of_school), name(name), age(age)
{
this->quantity_of_pupils += 1;
}
void print()
{
School::print();
cout << "name: " << name << " age: " << age << '\n';
}
};
int main()
{
School bettany("St. Carolina");
School marry("Borderland");
Pupil lexus(bettany, "Alexey", 18);
Pupil vlad(bettany, "Vlad", 20);
lexus.print();
bettany.print_quantity();
marry.print_quantity();
return 0;
}
Сделал ссылку и код заработал как необходимо
#include <iostream>
#include <string>
using namespace std;
class School
{
protected:
string name_of_school;
unsigned quantity_of_pupils{0};
public:
School(string name_of_school): name_of_school(name_of_school){}
void print()
{
cout << "school name: " << name_of_school << " ";
}
void print_quantity()
{
cout << "quantity of pupils: " << quantity_of_pupils << '\n';
}
void counter()
{
++quantity_of_pupils;
}
};
class Pupil : public School
{
private:
string name;
unsigned age;
public:
Pupil(School &name_of_school ,string name, unsigned age): School(name_of_school), name(name), age(age)
{
name_of_school.counter();
}
void print()
{
School::print();
cout << "name: " << name << " age: " << age << '\n';
}
};
int main()
{
School bettany("St. Carolina");
School marry("Borderland");
Pupil lexus(bettany, "Alexey", 18);
Pupil vlad(bettany, "Vlad", 20);
lexus.print();
bettany.print_quantity();
marry.print_quantity();
return 0;
}
Ответы (1 шт):
Почему у вас Ученик наследует Школу?
HolyBlackCat: Ученик не должен наследоваться от школы, потому что не является подвидом школы.
Если бы у вас было, например, наследование такого плана: Человек -> Ученик, т.е. все ученики являются людьми, то всё бы было правильно. Теперь давайте посмотрим, что у вас получается (School -> Pupil): все ученики являются школами...
Ваш код можно как-то так переформатировать, но лучше не мудрить и просто содать классы Pupil и School, и в School хранить vector, без указателей друг на друга...
Pupil.hpp
#ifndef PUPIL_HPP
#define PUPIL_HPP
#include <string>
#include <iostream>
class School;
class Pupil {
int id;
size_t age;
std::string name;
School* my_school;
static int max_id;
public:
Pupil();
Pupil(const std::string&, size_t);
int get_id() const;
size_t get_age() const;
School* get_school() const;
std::string get_name() const;
void change_age(size_t);
bool set_school(School*);
void change_name(const std::string&);
explicit operator bool() const;
bool operator==(const Pupil&) const;
friend std::ostream& operator<<(std::ostream&, const Pupil&);
};
#endif
Pupil.cpp
#include "Pupil.hpp"
#include "School.hpp"
// ---------- //
// - public - //
// ---------- //
/* Static Variables */
int Pupil::max_id = -1;
/* Constructors */
Pupil::Pupil(): Pupil("", 0) {}
Pupil::Pupil(const std::string& name, size_t age): my_school(nullptr), name(name), age(age), id(++max_id) {}
/* Getters */
int Pupil::get_id() const { return id; }
size_t Pupil::get_age() const { return age; }
std::string Pupil::get_name() const { return name; }
School* Pupil::get_school() const { return my_school; }
/* Setters */
void Pupil::change_age(size_t new_age) { age = new_age; }
void Pupil::change_name(const std::string& new_name) { name = new_name; }
bool Pupil::set_school(School* my_school) {
if(!my_school) { return false; }
for(const Pupil& ppl: *my_school)
if(ppl == *this) {
this->my_school = my_school;
return true;
}
return false;
}
/* Operators */
bool Pupil::operator==(const Pupil& other) const { return id == other.id; }
Pupil::operator bool() const { return my_school != nullptr && name != "" && age != 0; }
// ---------- //
// - friend - //
// ---------- //
std::ostream& operator<<(std::ostream& out, const Pupil& other) {
out << "Pupil(";
if(other) {
out << "name: " << other.name << "; ";
out << "age: " << other.age;
}
out << ')';
return out;
}
School.hpp
#ifndef SCHOOL_HPP
#define SCHOOL_HPP
#include <vector>
#include "Pupil.hpp"
class School {
std::string name;
size_t number_of_pupils;
std::vector<Pupil> pupils;
public:
School();
School(const std::string&);
Pupil& at(size_t);
size_t size() const;
bool add_pupil(const Pupil&);
std::vector<Pupil>::iterator end();
std::vector<Pupil>::iterator begin();
explicit operator bool() const;
friend std::ostream& operator<<(std::ostream&, const School&);
};
#endif
School.cpp
#include "School.hpp"
// ---------- //
// - public - //
// ---------- //
/* Constructors */
School::School(): School("") {}
School::School(const std::string& name): name(name), number_of_pupils(0) {}
/* Getters */
Pupil& School::at(size_t i) { return pupils[i]; }
size_t School::size() const { return number_of_pupils; }
/* Main Class Fuctions */
bool School::add_pupil(const Pupil& ppl) {
if(ppl.get_school()) { return false; }
++number_of_pupils;
pupils.push_back(ppl);
pupils.back().set_school(this);
return true;
}
/* for-loop iterators */
std::vector<Pupil>::iterator School::end() { return pupils.end(); }
std::vector<Pupil>::iterator School::begin() { return pupils.begin(); }
/* Operators */
School::operator bool() const { return name != ""; }
// ---------- //
// - friend - //
// ---------- //
std::ostream& operator<<(std::ostream& out, const School& other) {
out << "School{";
if(other) {
out << "name: " << other.name << "; ";
out << "pupils: [";
if(!other.pupils.empty()) {
out << other.pupils[0];
for(size_t i = 1; i < other.size(); ++i)
out << ", " << other.pupils[i];
}
out << ']';
}
out << '}';
return out;
}
main.cpp
#include "School.hpp"
int main() {
School marry("Borderland");
School bettany("St. Carolina");
Pupil vlad("Vlad", 20);
Pupil lexus("Alexey", 18);
bettany.add_pupil(vlad);
bettany.add_pupil(lexus);
std::cout << marry << '\n';
std::cout << bettany << '\n';
return 0;
}
Вывод:
School{name: Borderland; pupils: []}
School{name: St. Carolina; pupils: [Pupil(name: Vlad; age: 20), Pupil(name: Alexey; age: 18)]}