| Другое > Hard'n'Soft |
| Програмирование на C++ |
| << < (13/25) > >> |
| 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 блока и ловится для обработки.(вроде так, я этим не пользуюсь ;)) |
| Навигация |
| Главная страница сообщений |
| Следующая страница |
| Предыдущая страница |