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

Перейти к полной версии