
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.86] |
![]() |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток. я тут в процессе обучения реализовал пример из Страуструпа и наткнулся на проблему, пример работает только при подключенной строке
![]() ![]() #include <iostream.h> а при ![]() ![]() #include <iostream> не хочет работать (( Почему не хочет никак не пойму, я думал эти библиотеки практически одинаковые, только iosrteam стандартизована... Вот код программы, реализован под Visual C++ 6.0: ![]() ![]() #include <iostream> #include <string.h> #include <stdlib.h> using namespace std; class string { struct srep { char* s; int n; //счетчик числа ссылок srep() {n = 1;} }; srep* p; public: string(const char*); string(); string(const string &); string& operator =(const char *); string& operator =(const string &); ~string(); char & operator [](int i); friend ostream& operator <<(ostream&, const string&); friend istream& operator >>(istream&, string&); friend int operator ==(const string & x, const char* s) { return 0 == strcmp(x.p->s,s); } friend int operator ==(const string & x, const string & y) { return 0 == strcmp(x.p->s,y.p->s); } friend int operator !=(const string & x, const char* s) { return 0 != strcmp(x.p->s,s); } friend int operator !=(const string & x, const string & y) { return 0 != strcmp(x.p->s,y.p->s); } }; string::string() { p = new srep; p->s = 0; } string::string(const string& x) { x.p->n++; p = x.p; } string::string(const char* s) { p = new srep; p->s = new char[strlen(s) + 1]; strcpy(p->s,s); } string::~string() { if (0 == --p->n) { delete[] p->s; delete p; } } string& string::operator =(const char* s) { if (p->n > 1) { // отсоединяемся от старой строки p->n--; p = new srep; } else // освобождаем строку со старым значением delete p->s; p->s = new char[strlen(s) + 1]; strcpy(p->s,s); return *this; } string& string::operator =(const string& x) { x.p->n++; // защита от случая "st = st" if (0 == --p->n) { delete[] p->s; delete p; } p = x.p; return *this; } ostream& operator <<(ostream& s, const string& x) { return s << x.p->s << "[" << x.p->n << "]\n"; } istream& operator >>(istream& s, string& x) { char buf[256]; s >> buf; // ненадежно, возможно переполнение buf // см. 10,3 x = buf; cout << "echo: " << x << "\n"; return s; } void error(const char* p) { cerr << p << "\n"; exit(1); } char& string::operator [](int i) { if (i<0 || strlen(p->s)<i) error("недопустимое значение индекса"); return p->s[i]; } int main() { string x[100]; int n; cout << "здесь начало\n"; for(n=0; cin>>x[n]; n++) { if (100 == n) { error("слишком много слов"); return 99; } string y; cout << (y = x[n]); if (y == "doun") break; } cout << "теперь мы идем по словам в обратном порядке \n"; for(int i=n-1; 0<=i; i--) cout << x[i]; return 0; } |
Сообщ.
#2
,
|
|
|
Кажется в iostream.h по умолчанию используется пространство имен std.
Если не прав поправьте.. |
Сообщ.
#3
,
|
|
|
Цитата Druid @ Почему не хочет никак не пойму, я думал эти библиотеки практически одинаковые, только iosrteam стандартизована... В iostream.h все классы объявлены в глобальном пространстве имен, а в iostream - в пространстве std. По этому при использовании iostream тебе надо либо в начале файла указать \ using namespace std; либо перед каждым упоминанием имени из iostream ставить std:: |
Сообщ.
#4
,
|
|
|
А какой у тебя компилятор ? похоже борланд, так он в <iostream.h> делает include stlport\iostream и потом using namespace std;
Цитата Flex Ferrum @ В iostream.h все классы объявлены в глобальном пространстве имен, ![]() |
Сообщ.
#5
,
|
|
|
Так в примере при замене библиотеки с <iostream.h> на <iostream> еще и прописывается строка
![]() ![]() using namespace std; Без нее компилятор выдает вообще 42 ошибки )) Он при смене библиотеки начинает придираться к перегрузке операций почему-то... |
Сообщ.
#6
,
|
|
|
Цитата Druid @ Он при смене библиотеки начинает придираться к перегрузке операций почему-то... В таком случае ошибки и код в студию. |
Сообщ.
#7
,
|
|
|
error C2872: 'string' : ambiguous symbol
error C2872: 'string' : ambiguous symbol error C2872: 'string' : ambiguous symbol error C2248: 'p' : cannot access private member declared in class 'string' see declaration of 'p' error C2248: 'p' : cannot access private member declared in class 'string' see declaration of 'p' error C2872: 'string' : ambiguous symbol error C2593: 'operator <<' is ambiguous error C2872: 'string' : ambiguous symbol error C2593: 'operator >>' is ambiguous error C2872: 'string' : ambiguous symbol error C2593: 'operator <<' is ambiguous error C2593: 'operator <<' is ambiguous Error executing cl.exe. main1.obj - 12 error(s), 0 warning(s) Ошибки почти везде где есть перегрузка операций |
Сообщ.
#8
,
|
|
|
Сообщ.
#9
,
|
|
|
Спасибо за ссылки, сейчас почитаю...
|
Сообщ.
#10
,
|
|
|
1. К чему тут объявлен класс string?
2. В данном примере, если хочется оставить свой класс string, можно внести его в свое простанство имен: ![]() ![]() #include <iostream> #include <string.h> #include <stdlib.h> using namespace std; namespace my{ class string { struct srep { char* s; int n; //счетчик числа ссылок srep() {n = 1;} }; srep* p; public: string(const char*); string(); string(const string &); string& operator =(const char *); string& operator =(const string &); ~string(); char & operator [](int i); friend ostream& operator <<(ostream&, const string&); friend istream& operator >>(istream&, string&); friend int operator ==(const string & x, const char* s) { return 0 == strcmp(x.p->s,s); } friend int operator ==(const string & x, const string & y) { return 0 == strcmp(x.p->s,y.p->s); } friend int operator !=(const string & x, const char* s) { return 0 != strcmp(x.p->s,s); } friend int operator !=(const string & x, const string & y) { return 0 != strcmp(x.p->s,y.p->s); } }; .... } void error(const char* p) { cerr << p << "\n"; exit(1); } int main() { my::string x[100]; int n; cout << "здесь начало\n"; for(n=0; cin>>x[n]; n++) { if (100 == n) { error("слишком много слов"); return 99; } my::string y; cout << (y = x[n]); if (y == "doun") break; } cout << "теперь мы идем по словам в обратном порядке \n"; for(int i=n-1; 0<=i; i--) cout << x[i]; return 0; } |
Сообщ.
#11
,
|
|
|
<iostream> - это по новому стандарту. Раньше было <iostream.h>
Что касается using-определений, рекомендуется подключать только необходимые в проекте классы/функции, чтобы не потревожить внутренности STL. Что ты и сделал, переопрелив стандартный класс string ![]() |
Сообщ.
#12
,
|
|
|
Чтобы не потревожить внутренности, надо создавать свое пространство имен(namespace)
|
Сообщ.
#13
,
|
|
|
Переименовал класс и все с ним связанное из string в string_my ошибки уменьшились. Поместил новый класс string_my в новое пространство имен my и ошибки исчезли совсем.
А как теперь обращаться к функциям-членам из функции main() ![]() ![]() my::string_my::<нужная функция> ? Указывать сперва пространство, потом имя класса, если их несколько в моем пространстве имен, а потом нужную мне функцию? |
Сообщ.
#14
,
|
|
|
Цитата Druid @ А как теперь обращаться к функциям-членам из функции main()? <имя объект>-><имя функции> или <имя объект>.<имя функции>. ![]() ![]() my::A a; a.f(); |
Сообщ.
#15
,
|
|
|
Есть еще вопрос не по созданной теме, но по приведенному примеру.
Когда операторную функцию нужно определять как функцию-член, а когда как глобальную с описанием Friend ??? |
Сообщ.
#16
,
|
|
|
Цитата Переименовал класс и все с ним связанное из string в string_my ошибки уменьшились. Поместил новый класс string_my в новое пространство имен my и ошибки исчезли совсем. Если не ошибаюсь, просто в <iostream> уже есть свой класс string |
Сообщ.
#17
,
|
|
|
Цитата kalexs_uzb @ <имя объект>-><имя функции> или <имя объект>.<имя функции>. ![]() ![]() my::A a; a.f(); то есть пространство имен указывается один раз при вызове кноструктора, а потом к объекту можно обращаться как обычно? |
Сообщ.
#18
,
|
|
|
Цитата Druid @ то есть пространство имен указывается один раз при вызове кноструктора, а потом к объекту можно обращаться как обычно? следи за определениями: в какой области объявлен класс A? В my, значит пишем my::A в какой области объявлен объект a? В общей, значит пишем a Советую почитать Страуструпа |
Сообщ.
#19
,
|
|
|
Так пример из Страуструпа и есть :)
Спасибо всем за помощь ) |