Автор Тема: Програмирование на C++  (Прочитано 76699 раз)

0 Пользователей и 3 Гостей просматривают эту тему.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #240 : 03 Апрель 2011, 12:09:43 »
Цитата
В объявлении класса указывай пространство имён.(std::string)
Ах вот ещё что, ему класс string был нужен... Для этого надо string инклюдить, а не cstring.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #241 : 03 Апрель 2011, 13:34:25 »
Цитата: HoRRoR
Не заметил прикреплённые сорцы. Скажу сразу, CPP-ФАЙЛЫ НЕ ИНКЛЮДЯТ! Знай разницу между объектным файлом и заголовком.
То я от безысходности  :)
Но дело не в main, дело в Package.cpp, cstring  и просто stirng  я тоже пробовал подключать но это ничего не меняет - компилятор в ошибках выдаёт что не понимает что такое тип string. Собственно почему он не понимает? Я ведь ничего особенного не делаю, подключил библиотеку string и хочу чтобы в private были данные типа string, что же в этом такого?

Добавлено позже:
У Дейтела было всё ок, но подключал он всё что надо всегда в .h файле, и себе попробовать так чтоли ... но вопрос всё же актуален: почему к cpp файлу класса нельзя подключить через include строки (string)?

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #242 : 03 Апрель 2011, 13:34:27 »
Тебе же Mr2 объяснил. Либо прописывай using namespace std, либо пиши std::string.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #243 : 03 Апрель 2011, 13:42:37 »
Хм, вспомнив о пространстве имён дописал в том классе своём тоже using namespace std и ... теперь всё ок. Но почему? Я думал к пространству имён std у нас относится поток, табуляция, endl и т.д, а string тут непричом.

Добавлено позже:
HoRRoR,да вот конкретно всюду приписывать string:: не получилось - всё равно не захотело понимать меня что-то. Но я вижу что я до конца не понимаю что же представляет собой пространство имён std так обидно ещё что и в гугле только ссылки на форумы бросает где пытаются его подключить чтобы программа заработала, а не описывается более подробно что он из себя представляет.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #244 : 03 Апрель 2011, 13:44:40 »
Блин, ну наверное потому, что string тоже находится в пространстве имён std. Как и vector, list и прочие классы stl.

Добавлено позже:
Цитата
HoRRoR,да вот конкретно всюду приписывать string:: не получилось - всё равно не захотело понимать меня что-то. Но я вижу что я до конца не понимаю что же представляет собой пространство имён std так обидно ещё что и в гугле только ссылки на форумы бросает где пытаются его подключить чтобы программа заработала, а не описывается более подробно что он из себя представляет.
А ты не string:: приписывай, а std::.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #245 : 03 Апрель 2011, 15:05:43 »
Почему у Дейтела в .h файле всё подключалось и работало я уже понял - у него дописано ещё после  директивы include
using std::string;

Добавлено позже:
Цитата: HoRRoR
А ты не string:: приписывай, а std::.
Спасибо, я до этого думал что это разные пространства имён.

Добавлено позже:
Мда, оказывается при наследовании без
#ifndef PACKAGE_H
#define PACKAGE_H
...
#endif

Не обойтись, иначе потом в main (где я подключаю и базовый класс и класс наследующий тот базовый (так надо)) пишет что я пытаюсь переобозначить класс Package, хотя странно это с моей точки зрения. Ну добавило бы два раза тот же самый код и что, ничего страшного не случилось бы и по идеи должно было скомпилироваться  :)
Но раз надо значить надо.

Оффлайн Mr2

  • Пользователь
  • Сообщений: 1594
  • Пол: Мужской
  • Free roaming sorcerer
    • Facebook
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #246 : 03 Апрель 2011, 16:01:17 »
Ну добавило бы два раза тот же самый код и что, ничего страшного не случилось бы и по идеи должно было скомпилироваться  :)
Но раз надо значить надо.
Не код, а определение. А определяют только один раз. ;)


Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #247 : 03 Апрель 2011, 16:55:14 »
Цитата
Ну добавило бы два раза тот же самый код и что, ничего страшного не случилось бы и по идеи должно было скомпилироваться
Ну дерзай, напиши два раза один и тот же код, посмотрим, как он скомпилируется  :biggrin:

Цитата
А определяют только один раз.
Неверно. Есть ещё такая вещь, как undef.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #248 : 03 Апрель 2011, 19:24:45 »
Цитата: HoRRoR
Ну дерзай, напиши два раза один и тот же код, посмотрим, как он скомпилируется 
Ну так тот же класс string можно инклюдить сколько влезет в каждом отдельном классе и в итоге в main при подключении всех этих отдельных классов в каждом из которых подключена string при компиляции в код будет добавлено несколько копий этой string если я не ошибаюсь, почему же мой класс тогда нельзя вот так пару раз добавить в код, так не честно  :)
Цитата: HoRRoR
Неверно. Есть ещё такая вещь, как undef.
А это что?
Ну здесь как  понимаю ifndef - if not define , а что такое  undef ?
Тут ещё, блин, преподша какую-то graphics.h использует у себя в лабе, а в minigw ею и не пахнет, где бы её скачать и какой вообще есть хороший ресурс чтобы можно было тянуть самые популярные, но не идущие изначально с компилятором, классы?

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #249 : 03 Апрель 2011, 19:37:22 »
Цитата
Ну так тот же класс string можно инклюдить сколько влезет в каждом отдельном классе и в итоге в main при подключении всех этих отдельных классов в каждом из которых подключена string при компиляции в код будет добавлено несколько копий этой string если я не ошибаюсь, почему же мой класс тогда нельзя вот так пару раз добавить в код, так не честно
А ты открой исходник string:
#ifndef _GLIBCXX_STRING
#define _GLIBCXX_STRING 1

...

#endif /* _GLIBCXX_STRING */

Цитата
А это что?
Undefine. Смысл, думаю, ясен.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #250 : 07 Апрель 2011, 19:08:53 »
Мучу тут пример Дейтела на полиморфизм и наследование. Так вот всё работает но head файл базовый класс, который наследуют остальные классы, не компилируется если после
#ifndef EMPLOYEE_H
#define EMPLOYEE_H

не поставить ;  :? По какой причине такое может быть? Я не могу понять как может такое возникнуть именно с head файлом базового класса, который у меня выглядит
сам класс выглядит

Сорри, комментариев нет так как это базовый пример из книги, решил перепечатать так как пока перепечатаешь всегда где-то допустишь ошибку и пока её выудишь лучше поймёшь пример, но в этот раз я все ошибки выудил но почему возникает последняя без ; перед объявлением базового класса в .h файле я не понял. Не подскажете почему так?

Добавлено позже:
Написал отдельно main чисто для тестирования класса Employee и он компилируется и с ; после#define EMPLOYEE_H  и без неё.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #251 : 07 Апрель 2011, 19:18:45 »
У меня всё компилируется, какую ошибку выдавало? Скорей всего у тебя где-то в другом файле не поставлен разделитель или же чего-то не учёл. В следующий раз выкладывай весь код.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #252 : 07 Апрель 2011, 19:22:57 »
HoRRoR, беда в том что пример большой, не хотел пугать, думал можно будет и так определить куда копать, ну тогда ... смотрим прикреплённый файл.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #253 : 07 Апрель 2011, 19:27:29 »
CommissionEmployee.cpp:
using std::cout;
using std::string
Пропущена точка с запятой.

P.S. Плохая привычка писать код перед инклюдами. h-файлы должны быть независимы, т.е. в них самих надо прописывать unsing ..., а не в cpp.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #254 : 07 Апрель 2011, 19:35:39 »
HoRRoR,тут понял, те получалось что в код CommissionEmployee.cpp после using std::string добавлялся код Employee.h, но так как ; была пропущена ... В общем теперь понятно почему возникла ошибка, спасибо. Непонятно только почему оно не намекнуло хоть как-то на то что ошибка связана косвенно с  CommissionEmployee.cpp.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #255 : 07 Апрель 2011, 19:56:21 »
А ты бы сам поразмыслил ;) Просто ошибка становится явной только в 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

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #256 : 08 Апрель 2011, 00:52:51 »
Читаю что-то тут о полиморфизме и не сильно пока замечаю его мега преимуществ, ну можем мы пользоваться указателями на базовый класс и вызывать через них потом реализации функций от класса наследующего базовый класс, но толку? Как-то всё вполне логично и эффект "вау" не возник, вот наследование интересная и удобная штука. Хотя я правда раздел ещё не дочитал, может я ещё изменю своё мнение.

Добавлено позже:
И ещё:  когда мы используем  полиморфизм то для каждой виртуальной функции получается при выполнении в памяти держится куча реализаций и выбирается нужная уже при вызове, так? А если у меня там много классов за счёт наследование и будет сотня реализаций виртуальных функций то это всё постоянно будет висеть в памяти чтобы в любой момент была возможность вызова нужной вирт. функции?

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #257 : 08 Апрель 2011, 01:04:37 »
Цитата
Читаю что-то тут о полиморфизме и не сильно пока замечаю его мега преимуществ, ну можем мы пользоваться указателями на базовый класс и вызывать через них потом реализации функций от класса наследующего базовый класс, но толку? Как-то всё вполне логично и эффект "вау" не возник, вот наследование интересная и удобная штука. Хотя я правда раздел ещё не дочитал, может я ещё изменю своё мнение.

А ты сравни, к примеру, эти два куска:

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);
}

Цитата
И ещё:  когда мы используем  полиморфизм то для каждой виртуальной функции получается при выполнении в памяти держится куча реализаций и выбирается нужная уже при вызове, так? А если у меня там много классов за счёт наследование и будет сотня реализаций виртуальных функций то это всё постоянно будет висеть в памяти чтобы в любой момент была возможность вызова нужной вирт. функции?
Каждая реализация - это отдельная функция. Естественно, они все присутствуют в памяти, как и другой статический код.
« Последнее редактирование: 08 Апрель 2011, 12:50:06 от HoRRoR »

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #258 : 08 Апрель 2011, 19:34:31 »
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 добавляет какие-то цифры и от чего зависят эти цифры?

Надеюсь ответы на мои маленькие вопросы , когда хорошо знаешь язык с++, не занимаю много времени  :)
« Последнее редактирование: 08 Апрель 2011, 20:22:11 от gepar »

Оффлайн Mr2

  • Пользователь
  • Сообщений: 1594
  • Пол: Мужской
  • Free roaming sorcerer
    • Facebook
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #259 : 08 Апрель 2011, 20:16:30 »
И ещё вопрос: что такое try и catch?
Я случайно в вики наткнулся когда смотрел пример: http://ru.wikipedia.org/wiki/Dynamic_cast
Пытаешься выполнить код, если в коде есть ошибка она выбрасывается из try блока и ловится для обработки.(вроде так, я этим не пользуюсь ;))

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #260 : 08 Апрель 2011, 21:03:08 »
Цитата
И ещё вопрос: что такое try и catch?
Я случайно в вики наткнулся когда смотрел пример: http://ru.wikipedia.org/wiki/Dynamic_cast
Перехват исключений. Т.е., например, деление на ноль - исключение, приложение выдаст ошибку. Но если ты это исключение перехватишь, то ошибки не будет - это будет часть твоего алгоритма. Также ты можешь генерировать свои исключения.

Цитата
почему в примере Дейтела typeid <...>.name возвращает просто название класса, а у меня XXназвание класса, где X - цифра. Я так понимаю это зависит от компилятора, но зачем тогда minigw возвращает какие-то левые  цифры и что они означают?
На всякий случай прикрепляю пример.
UPD: Дейтел пишет что компиляторы могут выдавать по этому поводу что угодно, но зачем тогда minigw добавляет какие-то цифры и от чего зависят эти цифры?
Уж чего не знаю - того не знаю. Гугли...

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #261 : 10 Апрель 2011, 17:52:38 »
Так и не поборол что typeid(...).name() выдаёт цифры в итоге вывод идиотский получается  :(

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #262 : 10 Апрель 2011, 18:50:19 »
Видимо, это для уникальности имён, чтобы два разных типа с одним именем и через typeid давали разные имена.

Добавлено позже:
Ты можешь просто удалять все цифры из начала - имя типа не может начинаться с цифры, так что ты получишь «чистое» имя типа.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #263 : 10 Апрель 2011, 19:08:00 »
HoRRoR,а как я это сделаю ? Если допустим у меня будет строка с вот таким вот названием то как определить принадлежность к цифрами или символам (только не через switch же)? Отрезать просто первые два символа не получиться - иногда одну цифру перед названием оно возвращает, а иногда две, предугадать сложно.

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #264 : 10 Апрель 2011, 19:23:26 »
Примерно так:
const char* getName(const char* name)
{
    const char* c = name;
    while(*c && *c >= '0' && *c <='9') c++;
    return c;
}


Добавлено позже:
А есть ещё функция isdigit, которая заменяет собой *c >= '0' && *c <= '9'.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #265 : 10 Апрель 2011, 22:24:40 »
HoRRoR, ну когда я писал "только не switch" то я догадывался что можно же ещё и циклом вот так гонять, но это тоже как-то не тру, хотя вроде наиболее практично.
Цитата: HoRRoR
А есть ещё функция isdigit, которая заменяет собой *c >= '0' && *c <= '9'.
А что для неё инклюдить надо?

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #266 : 10 Апрель 2011, 23:04:02 »
Цитата
HoRRoR, ну когда я писал "только не switch" то я догадывался что можно же ещё и циклом вот так гонять, но это тоже как-то не тру, хотя вроде наиболее практично.
Лолшто? С чего бы это было не тру? Вот как раз свич был не к месту.

Цитата
А что для неё инклюдить надо?
Можно было и загуглить. cctype.

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #267 : 10 Апрель 2011, 23:08:35 »
Цитата: HoRRoR
Можно было и загуглить. cctype.
Загуглил, ничего ему не надо  :)
Но всё равно что-то я никак не могу придумать как хитро удалить из моей строки цифры собственно цикл мой:
   for(int i=0;i<shape.size();i++) //цикл по всем элементам вектора
    {
        Thshape *temp=dynamic_cast<Thshape*> (shape[i]);
        cout<<"Figure ";
        if (isdigit(typeid(*shape[i]).name()[1])) // Если второй символ в названии что вернёт typeid(..).name() цифра то

         strcpy(abc,typeid(*shape[i]).name()[1]); //надо бы как-то удалить первые две цифры из строки/скопировать строку без этих первых двух символов, но не так как я написал
        cout<<abc<<" Area: "<<shape[i]->getArea();
        if (temp) //если фигура трёхмерная
         cout<<" Volume: "<<temp->getVolume();
        cout<<endl;
    }

Оффлайн HoRRoR

  • Пользователь
  • Сообщений: 983
  • Пол: Мужской
  • Ромхакер
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #268 : 10 Апрель 2011, 23:20:54 »
Цитата
Загуглил, ничего ему не надо
Лолшто?

Цитата
Но всё равно что-то я никак не могу придумать как хитро удалить из моей строки цифры собственно цикл мой:
Господи, определяешь позицию первого символа-не-цифры, и с неё копируешь.
« Последнее редактирование: 10 Апрель 2011, 23:23:31 от HoRRoR »

Оффлайн gepar

  • Пользователь
  • Сообщений: 10150
  • Пол: Мужской
  • ▂ ▃ ▄ ▅ ▆ ▇ █
    • Просмотр профиля
Re: Програмирование на C++
« Ответ #269 : 11 Апрель 2011, 00:41:52 »
HoRRoR,так с определением того одна или две у меня цифры проблем и не возникает. Проблема возникает с копированием из строки с заданной позиции или с удалением заданного числа символов из этой строки  с последующим сдвигом оставшихся символов.

Добавлено позже:
Цитата: HoRRoR
Лолшто?
У меня не просит оно никаких сиситайпов так что не знаю, но буду иметь в виду что подключить если попросит  :)