Другое > Hard'n'Soft
Програмирование на C++
HoRRoR:
--- Цитата ---В объявлении класса указывай пространство имён.(std::string)
--- Конец цитаты ---
Ах вот ещё что, ему класс string был нужен... Для этого надо string инклюдить, а не cstring.
gepar:
--- Цитата: HoRRoR ---Не заметил прикреплённые сорцы. Скажу сразу, CPP-ФАЙЛЫ НЕ ИНКЛЮДЯТ! Знай разницу между объектным файлом и заголовком.
--- Конец цитаты ---
То я от безысходности :)
Но дело не в main, дело в Package.cpp, cstring и просто stirng я тоже пробовал подключать но это ничего не меняет - компилятор в ошибках выдаёт что не понимает что такое тип string. Собственно почему он не понимает? Я ведь ничего особенного не делаю, подключил библиотеку string и хочу чтобы в private были данные типа string, что же в этом такого?
Добавлено позже:
У Дейтела было всё ок, но подключал он всё что надо всегда в .h файле, и себе попробовать так чтоли ... но вопрос всё же актуален: почему к cpp файлу класса нельзя подключить через include строки (string)?
HoRRoR:
Тебе же Mr2 объяснил. Либо прописывай using namespace std, либо пиши std::string.
gepar:
Хм, вспомнив о пространстве имён дописал в том классе своём тоже using namespace std и ... теперь всё ок. Но почему? Я думал к пространству имён std у нас относится поток, табуляция, endl и т.д, а string тут непричом.
Добавлено позже:
HoRRoR,да вот конкретно всюду приписывать string:: не получилось - всё равно не захотело понимать меня что-то. Но я вижу что я до конца не понимаю что же представляет собой пространство имён std так обидно ещё что и в гугле только ссылки на форумы бросает где пытаются его подключить чтобы программа заработала, а не описывается более подробно что он из себя представляет.
HoRRoR:
Блин, ну наверное потому, что string тоже находится в пространстве имён std. Как и vector, list и прочие классы stl.
Добавлено позже:
--- Цитата ---HoRRoR,да вот конкретно всюду приписывать string:: не получилось - всё равно не захотело понимать меня что-то. Но я вижу что я до конца не понимаю что же представляет собой пространство имён std так обидно ещё что и в гугле только ссылки на форумы бросает где пытаются его подключить чтобы программа заработала, а не описывается более подробно что он из себя представляет.
--- Конец цитаты ---
А ты не string:: приписывай, а std::.
gepar:
Почему у Дейтела в .h файле всё подключалось и работало я уже понял - у него дописано ещё после директивы include
using std::string;
Добавлено позже:
--- Цитата: HoRRoR ---А ты не string:: приписывай, а std::.
--- Конец цитаты ---
Спасибо, я до этого думал что это разные пространства имён.
Добавлено позже:
Мда, оказывается при наследовании без
#ifndef PACKAGE_H
#define PACKAGE_H
...
#endif
Не обойтись, иначе потом в main (где я подключаю и базовый класс и класс наследующий тот базовый (так надо)) пишет что я пытаюсь переобозначить класс Package, хотя странно это с моей точки зрения. Ну добавило бы два раза тот же самый код и что, ничего страшного не случилось бы и по идеи должно было скомпилироваться :)
Но раз надо значить надо.
Mr2:
--- Цитата: gepar от 03 Апреля 2011, 15:05:43 ---Ну добавило бы два раза тот же самый код и что, ничего страшного не случилось бы и по идеи должно было скомпилироваться :)
Но раз надо значить надо.
--- Конец цитаты ---
Не код, а определение. А определяют только один раз. ;)
HoRRoR:
--- Цитата ---Ну добавило бы два раза тот же самый код и что, ничего страшного не случилось бы и по идеи должно было скомпилироваться
--- Конец цитаты ---
Ну дерзай, напиши два раза один и тот же код, посмотрим, как он скомпилируется :biggrin:
--- Цитата ---А определяют только один раз.
--- Конец цитаты ---
Неверно. Есть ещё такая вещь, как undef.
gepar:
--- Цитата: HoRRoR ---Ну дерзай, напиши два раза один и тот же код, посмотрим, как он скомпилируется
--- Конец цитаты ---
Ну так тот же класс string можно инклюдить сколько влезет в каждом отдельном классе и в итоге в main при подключении всех этих отдельных классов в каждом из которых подключена string при компиляции в код будет добавлено несколько копий этой string если я не ошибаюсь, почему же мой класс тогда нельзя вот так пару раз добавить в код, так не честно :)
--- Цитата: HoRRoR ---Неверно. Есть ещё такая вещь, как undef.
--- Конец цитаты ---
А это что?
Ну здесь как понимаю ifndef - if not define , а что такое undef ?
Тут ещё, блин, преподша какую-то graphics.h использует у себя в лабе, а в minigw ею и не пахнет, где бы её скачать и какой вообще есть хороший ресурс чтобы можно было тянуть самые популярные, но не идущие изначально с компилятором, классы?
HoRRoR:
--- Цитата ---Ну так тот же класс string можно инклюдить сколько влезет в каждом отдельном классе и в итоге в main при подключении всех этих отдельных классов в каждом из которых подключена string при компиляции в код будет добавлено несколько копий этой string если я не ошибаюсь, почему же мой класс тогда нельзя вот так пару раз добавить в код, так не честно
--- Конец цитаты ---
А ты открой исходник string:
--- Код: ---#ifndef _GLIBCXX_STRING
#define _GLIBCXX_STRING 1
...
#endif /* _GLIBCXX_STRING */
--- Конец кода ---
--- Цитата ---А это что?
--- Конец цитаты ---
Undefine. Смысл, думаю, ясен.
gepar:
Мучу тут пример Дейтела на полиморфизм и наследование. Так вот всё работает но head файл базовый класс, который наследуют остальные классы, не компилируется если после
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
не поставить ; :? По какой причине такое может быть? Я не могу понять как может такое возникнуть именно с head файлом базового класса, который у меня выглядит
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
;
#include <string>
using std::string;
class Employee
{
public:
Employee(const string &, const string &, const string &);
void setFirstName(const string &);
string getFirstName() const;
void setLastName(const string &);
string getLastName() const;
void setSocialSecurityNumber(const string &);
string getSocialSecurityNumber() const;
virtual double earnings() const=0;
virtual void print() const;
private:
string firstName;
string lastName;
string socialSecurityNumber;
};
#endif
сам класс выглядит
# include <iostream>
using std::cout;
#include "Employee.h"
Employee::Employee(const string &first, const string &last,
const string &ssn)
:firstName(first), lastName(last), socialSecurityNumber(ssn)
{
}
void Employee::setFirstName(const string &first)
{
firstName=first;
}
string Employee::getFirstName() const
{
return firstName;
}
void Employee::setLastName(const string &last)
{
lastName=last;
}
string Employee::getLastName() const
{
return lastName;
}
void Employee::setSocialSecurityNumber(const string &ssn)
{
socialSecurityNumber=ssn;
}
string Employee::getSocialSecurityNumber() const
{
return socialSecurityNumber;
}
void Employee::print() const
{
cout<<getFirstName()<<' '<<getLastName()
<<"\nsocial security number: "<<getSocialSecurityNumber();
}
Сорри, комментариев нет так как это базовый пример из книги, решил перепечатать так как пока перепечатаешь всегда где-то допустишь ошибку и пока её выудишь лучше поймёшь пример, но в этот раз я все ошибки выудил но почему возникает последняя без ; перед объявлением базового класса в .h файле я не понял. Не подскажете почему так?
Добавлено позже:
Написал отдельно main чисто для тестирования класса Employee и он компилируется и с ; после#define EMPLOYEE_H и без неё.
HoRRoR:
У меня всё компилируется, какую ошибку выдавало? Скорей всего у тебя где-то в другом файле не поставлен разделитель или же чего-то не учёл. В следующий раз выкладывай весь код.
gepar:
HoRRoR, беда в том что пример большой, не хотел пугать, думал можно будет и так определить куда копать, ну тогда ... смотрим прикреплённый файл.
HoRRoR:
CommissionEmployee.cpp:
--- Код: ---using std::cout;
using std::string
--- Конец кода ---
Пропущена точка с запятой.
P.S. Плохая привычка писать код перед инклюдами. h-файлы должны быть независимы, т.е. в них самих надо прописывать unsing ..., а не в cpp.
gepar:
HoRRoR,тут понял, те получалось что в код CommissionEmployee.cpp после using std::string добавлялся код Employee.h, но так как ; была пропущена ... В общем теперь понятно почему возникла ошибка, спасибо. Непонятно только почему оно не намекнуло хоть как-то на то что ошибка связана косвенно с CommissionEmployee.cpp.
HoRRoR:
А ты бы сам поразмыслил ;) Просто ошибка становится явной только в employee.h.
Вот смотри, как у нас получается:
--- Код: ---using std::cout;
using std::string
#include "CommissionEmployee.h"
...
--- Конец кода ---
Инклюдим CommissionEmployee.h (т.е. сейчас мы находимся в нём):
--- Код: ---using std::cout;
using std::string
/* --> Здесь было #include "CommissionEmployee.h" <-- */
# ifndef COMMISSION_H
# define COMMISSION_H
# include "Employee.h"
...
--- Конец кода ---
Инклюдим Employee.h (теперь мы уже в нём):
--- Код: ---using std::cout;
using std::string
/* --> Здесь было #include "CommissionEmployee.h" <-- */
# ifndef COMMISSION_H
# define COMMISSION_H
/* --> Здесь было #include "Employee.h" <-- */
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
/* Вот где-то здесь становится известно об ошибке */
#include <string>
using std::string;
...
--- Конец кода ---
gepar:
Читаю что-то тут о полиморфизме и не сильно пока замечаю его мега преимуществ, ну можем мы пользоваться указателями на базовый класс и вызывать через них потом реализации функций от класса наследующего базовый класс, но толку? Как-то всё вполне логично и эффект "вау" не возник, вот наследование интересная и удобная штука. Хотя я правда раздел ещё не дочитал, может я ещё изменю своё мнение.
Добавлено позже:
И ещё: когда мы используем полиморфизм то для каждой виртуальной функции получается при выполнении в памяти держится куча реализаций и выбирается нужная уже при вызове, так? А если у меня там много классов за счёт наследование и будет сотня реализаций виртуальных функций то это всё постоянно будет висеть в памяти чтобы в любой момент была возможность вызова нужной вирт. функции?
HoRRoR:
--- Цитата ---Читаю что-то тут о полиморфизме и не сильно пока замечаю его мега преимуществ, ну можем мы пользоваться указателями на базовый класс и вызывать через них потом реализации функций от класса наследующего базовый класс, но толку? Как-то всё вполне логично и эффект "вау" не возник, вот наследование интересная и удобная штука. Хотя я правда раздел ещё не дочитал, может я ещё изменю своё мнение.
--- Конец цитаты ---
А ты сравни, к примеру, эти два куска:
--- Код: ---void foo(X x)
{
x.abc();
}
...
x = newX(type);
foo(x);
--- Конец кода ---
--- Код: ---void foo(A x)
{
x.abc();
}
void foo(B x)
{
x.abc();
}
void foo(C x)
{
x.abc();
}
...
if(type == TYPE_A)
{
A a = newA();
foo(a);
}
else if(type == TYPE_B)
{
B b = newB();
foo(b);
}
else if(type == TYPE_C)
{
C c = newC();
foo(c);
}
--- Конец кода ---
--- Цитата ---И ещё: когда мы используем полиморфизм то для каждой виртуальной функции получается при выполнении в памяти держится куча реализаций и выбирается нужная уже при вызове, так? А если у меня там много классов за счёт наследование и будет сотня реализаций виртуальных функций то это всё постоянно будет висеть в памяти чтобы в любой момент была возможность вызова нужной вирт. функции?
--- Конец цитаты ---
Каждая реализация - это отдельная функция. Естественно, они все присутствуют в памяти, как и другой статический код.
gepar:
HoRRoR,с switch второй код выглядел бы более конкурентоспособным :)
Добавлено позже:
А каков смысл в типе size_t ? Ну вот у Дейтела строка например
for ( size_t j = 0; j < employees.size(); j++ )
Почему бы не воспользоваться более привычным int, экономия же памяти минимальна или у size_t типа есть какие-то особенности?
Добавлено позже:
И ещё вопрос: что такое try и catch?
Я случайно в вики наткнулся когда смотрел пример: http://ru.wikipedia.org/wiki/Dynamic_cast
Добавлено позже:
И ещё вопрос:
почему в примере Дейтела typeid <...>.name возвращает просто название класса, а у меня XXназвание класса, где X - цифра. Я так понимаю это зависит от компилятора, но зачем тогда minigw возвращает какие-то левые цифры и что они означают?
На всякий случай прикрепляю пример.
UPD: Дейтел пишет что компиляторы могут выдавать по этому поводу что угодно, но зачем тогда minigw добавляет какие-то цифры и от чего зависят эти цифры?
Надеюсь ответы на мои маленькие вопросы , когда хорошо знаешь язык с++, не занимаю много времени :)
Mr2:
--- Цитата: gepar от 08 Апреля 2011, 19:34:31 ---И ещё вопрос: что такое try и catch?
Я случайно в вики наткнулся когда смотрел пример: http://ru.wikipedia.org/wiki/Dynamic_cast
--- Конец цитаты ---
Пытаешься выполнить код, если в коде есть ошибка она выбрасывается из try блока и ловится для обработки.(вроде так, я этим не пользуюсь ;))
Навигация
Перейти к полной версии