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 шт):
Если Вы начинающий программист, учитесь читать ошибки, без этого никуда. В тексте Ваших ошибок всё доступно объяснено, но я сейчас постараюсь рассказать ещё подробнее. Итак, первые три ошибки:
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 будет неэффективно как для Вас, так и для участников сообщества.