error C2228: выражение должно представлять класс, структуру или объединение

Пытаюсь разобраться с наследованием, абстрактными классами и прочим в C++, однако никак не могу понять, когда использовать точку, а когда ->. Данный код не запускается ни с тем, ни с другим, не могу сообразить, что делаю не так. Надеюсь, поможете. Программа описывает паб, в котором работают сотрудник и супервайзер, могут прийти обычный и несовершеннолетний посетитель.
P.S. Делал бы некоторые вещи не так запутанно, но стараюсь влезть в требования лабораторной работы.
P.P.S. Просьба указать на все ошибки, корявости и возможности оптимизации, т.к. реально хочу освоить профессию.

#include <iostream>
#include <string>

using namespace std;

class Shop {
    
    public:
    
   string name;
   string owner;
   
   protected:
   
   virtual void open() = 0;
   virtual void numbers() = 0;
   virtual void close() = 0;
    
};

class Pub: public Shop {

public:

    Pub() {
        name = "PorterPub";
        owner = "HaveNoIdea";
    }

    Pub(string name, string owner) {
        this->name = name;
        this->owner = owner;
    }

    void open() {
        
        cout << name << " is open. \n";
    }

    void numbers() {

        cout << "There are " << numberOfVisitors << " of " << maximumNumberOfVisitors << " visitors. \n";
    }

    void close() {

        cout << name << " is closed. \n";
    }

    void setMaximumNumberOfVisitors(int maximumNumberOfVisitors) {

        this->maximumNumberOfVisitors = maximumNumberOfVisitors;
    }

    int getMaximumNumberOfVisitors() {

        return maximumNumberOfVisitors;
    }

    void setNumberOfVisitors(int numberOfVisitors) {

        this->numberOfVisitors = numberOfVisitors;
    }

    int getNumberOfVisitors() {
        
        return numberOfVisitors;
    }

private:

    int maximumNumberOfVisitors;
    int numberOfVisitors;

};

class Human {
 
 public:
 
    string name;
    int age;
    
    virtual void eat() {
        cout << "Human is eating.";
    }
    
    virtual void drink() {
        cout << "Human is drinking.";
    }
    
};

class Employee: public Human {

public:

    int experience;

    Employee() {

        name = "Maria";
        age = 21;
        experience = 3;
    }

    Employee(string name, int age, int experience) {

        this->name = name;
        this->age = age;
        this->experience = experience;

    }

    bool checkAge(int visitorsAge) {

        if(visitorsAge < 18) return false;

        return true;
    }

    void setTShirtColour(string tShirtColour) {

        this->tShirtColour = tShirtColour;
    }

    string getTShirtColour() {

        return tShirtColour;
    }

    void setNailsColour(string nailsColour) {

        this->nailsColour = nailsColour;
    }

    string getNailsColour() {

        return nailsColour;
    }

private:

    string tShirtColour;
    string nailsColour;
};

class Supervisor: public Employee {

public:

    string mood;
    int quantityOfEmployees;

    Supervisor() {
        
        mood = "Angry";
        quantityOfEmployees = 4;
    }

    Supervisor(string mood, int quantityOfEmployees) {
        
        this->mood = mood;
        this->quantityOfEmployees = quantityOfEmployees;
    }
    
    void discount(string visitorsName) {

        cout << "Supervisor gave " << visitorsName << " a discount!";
    }

    void setSalary(int salary) {

        this->salary = salary;
    }

    int getSalary() {

        return salary;
    }

    void setFavouriteDrink(string favouriteDrink) {

        this->favouriteDrink = favouriteDrink;
    }

    string getFavouriteDrink() {
        
        return favouriteDrink;
    }

private:

    int salary;
    string favouriteDrink;
};

class Visitor: public Human {

public:

    Visitor() {

        name = "Anastasia";
        age = 21;
    }

    Visitor(string name, int age) {

        this->name = name;
        this->age = age;

    }

    void drink() {

        cout << name << " is drinking. \n";
    }

    void eat() {

        cout << name << " is eating. \n";
    }

    void setHairColour(string hairColour) {

        this->hairColour = hairColour;
    }

    string getHairColour() {

        return hairColour;
    }

    void setEyeColour(string eyeColour) {

        this->eyeColour = eyeColour;
    }

    string getEyeColour() {

        return eyeColour;
    }

private:

    string hairColour;
    string eyeColour;
};

class UnderagedVisitor: public Visitor {

public:

    string state;
    string behaviour;

    UnderagedVisitor() {

        state = "Nervous";
        behaviour = "Self-righteous";
    }

    UnderagedVisitor(string state, string behaviour) {

        this->state = state;
        this->behaviour = behaviour;
    }

    void buyADrink(Supervisor supervisor) {
        
        cout << name << " bought supervisor " << supervisor.name << " some " << supervisor.getFavouriteDrink() << ". \n";
    }

    void setBag(string bag) {

        this->bag = bag;
    }

    string getBag() {

        return bag;
    }

    void setCompany(int company) {

        this->company = company;
    }

    int getCompany() {

        return company;
    }

private:

    string bag;
    int company;
};

void gaveADrink(string employee, string visitor) {
    
    cout << employee << " gave " << visitor << " a drink. \n";
}

void callASupervisor(string employee, string supervisor, string visitor) {
    
    cout << employee.name << " called a supervisor " << supervisor.name << " for " << visitor.name << ". \n";
}

int main() {

    Pub pub;
    pub.open();
    pub.setNumberOfVisitors(10);
    pub.setMaximumNumberOfVisitors(25);
    pub.numbers();

    Human *visitor;
    visitor = new Visitor;
    visitor->eat();
    visitor->drink();
    delete visitor;

    visitor = new UnderagedVisitor("Confident", "Shy");
    visitor->name = "Alex";
    visitor->age = 17;
    visitor.setBag("Backpack");
    
    Supervisor maria;
    maria.name = "Maria";
    maria.age = 21;
    maria.setFavouriteDrink("Tequila");
    maria.setSalary(10000);

    Employee dima("Dima", 25, 4);
    dima.setNailsColour("Skin colour");
    dima.setTShirtColour("Black");

    string *result = null;

    if(dima.checkAge(visitor.age)) result = gaveADrink(dima.name, visitor.name);
    else result = callASupervisor(dima.name, maria.name, visitor.name);
    visitor.buyADrink(maria);

    pub.close();

    system("pause");
    return 0;
}

Ошибки:

1>Lab4.cpp    
1>.\Lab4.cpp(308) : error C2039: name: не является членом "std::basic_string<_Elem,_Traits,_Ax>"  
  1>        with  
  1>        [  
  1>            _Elem=char,  
  1>            _Traits=std::char_traits<char>,  
  1>            _Ax=std::allocator<char>  
  1>        ]  
  1>.\Lab4.cpp(308) : error C2039: name: не является членом "std::basic_string<_Elem,_Traits,_Ax>"  
  1>        with  
  1>        [  
  1>            _Elem=char,  
  1>            _Traits=std::char_traits<char>,  
  1>            _Ax=std::allocator<char>  
  1>        ]  
  1>.\Lab4.cpp(308) : error C2039: name: не является членом 
"std::basic_string<_Elem,_Traits,_Ax>"  
  1>        with  
  1>        [  
  1>            _Elem=char,  
  1>            _Traits=std::char_traits<char>,  
  1>            _Ax=std::allocator<char>  
  1>        ]  
  1>.\Lab4.cpp(328) : error C2228: выражение слева от ".setBag" должно представлять класс, структуру или объединение  
  1>        тип: Human *  
  1>        возможно, имеется в виду '->'  
  1>.\Lab4.cpp(340) : error C2065: null: необъявленный идентификатор  
  1>.\Lab4.cpp(342) : error C2228: выражение слева от ".age" должно представлять класс, структуру или объединение  
  1>        тип: Human *  
  1>        возможно, имеется в виду '->'  
  1>.\Lab4.cpp(342) : error C2228: выражение слева от ".name" должно представлять класс, структуру или объединение  
  1>        тип: Human *  
  1>        возможно, имеется в виду '->'  
  1>.\Lab4.cpp(343) : error C2228: выражение слева от ".name" должно представлять класс, структуру или объединение  
  1>        тип: Human *  
  1>        возможно, имеется в виду '->'  
  1>.\Lab4.cpp(344) : error C2228: выражение слева от ".buyADrink" должно представлять класс, структуру или объединение  
1>        тип: Human *  
1>        возможно, имеется в виду '->'  

Прошу также простить, если вопрос задан некорректно: это мой первый опыт задавания вопросов на подобных платформах.


Ответы (1 шт):

Автор решения: V-Mor

Если Вы начинающий программист, учитесь читать ошибки, без этого никуда. В тексте Ваших ошибок всё доступно объяснено, но я сейчас постараюсь рассказать ещё подробнее. Итак, первые три ошибки:

error C2039: name: не является членом "std::basic_string<_Elem,_Traits,_Ax>"

Такой текст означает, что Вы пытались получить от объекта типа std::string его атрибут name (которого у него нет и не должно быть). Делалось это, очевидно, либо через -> либо через .. То есть, нам нужно искать в указанной строке что_то.name или что_то->name, где что_то имеет тип std::string. Смотрим на указанную строку, видим, что она входит в функцию:

void callASupervisor(string employee, string supervisor, string visitor) {
    
    cout << employee.name << " called a supervisor " << supervisor.name << " for " << visitor.name << ". \n";
}

И вот отсюда внимательно, смотрим первую строку с аргументами: stringemployee, stringsupervisor,stringvisitor. Видите жирное выделение? Все три аргумента типа string, тот самый std::string. А теперь смотрим на тело функции:

cout << employee.name << " called a supervisor " << supervisor.name << " for " << visitor.name << ". \n";

Откуда у аргументов типа string взялись атрибуты name? Я не знаю, компилятор тоже. Скорее всего, имелось в виду это:

cout << employee << " called a supervisor " << supervisor << " for " << visitor << ". \n";

Теперь ко второй группе ошибок. Тут всё проще. Напутали с . и ->. Единственное железное правило: работаете с указателем на объект – используете ->, работаете с самим объектом, используете .. Взболтать, но не смешивать! Ни в коем случае. Теперь к коду. У Вас есть Human *visitor;. * значит, что это указатель на объект. А значит везде после visitor должна стоять ->. Теперь ищем все места, где у Вас вместо -> стоит ., например:

if(dima.checkAge(visitor.age))

И меняем . на ->.

P.S. Ошибки и правда не сложные, и сдаётся мне, что, если бы Вы сами посидели с этим часик-другой, решение пришло бы Вам без помощи SO. Здесь я подробно описал, как искать свои ошибки и на что обращать внимание, но впредь старайтесь сами исправлять подобные опечатки, ибо то, что представлено в вопросе, является именно опечатками – случайной подменой символов по невнимательности. Они будут встречаться всегда, в большей или меньшей степени, и каждый раз писать на SO будет неэффективно как для Вас, так и для участников сообщества.

→ Ссылка