Druid
Гость
|
|
« : 03-05-2006 15:15 » |
|
Есть пример из книжки Страуструпа, пытаюсь реализовать в Visual C++ выдает 46 ошибок, в BC++ 3.1 выдает 4 ошибки. Помогите пожалуйста. Вот код: #include <iostream> #include <cstring>
class string { struct srep { char* s; int n; //счетчик числа ссылок srep() {n = 1;} };
srep* p;
public: string(const char*); srting(); 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::srting() { p = new srep; p->s = 0; }
string::srting(const string& x) { x.p = n++; p = x.p; }
string::srting(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; }
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #1 : 03-05-2006 15:36 » |
|
Druid, сами ошибки то же приведи.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #2 : 03-05-2006 16:41 » |
|
Места, где я вижу явные ошибки string::srting(const string& x) { x.p = n++; // <--- Тут явная ошибка. Опечатка. Скорее всего за место знака = надо ставить -> p = x.p; }
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 03-05-2006 16:59 » |
|
косяки: 1)
string::srting(const string& x) { x.p = n++; p = x.p; }
- очепятка + неопределена n
дальше - не знаю, всякое может быть
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #4 : 03-05-2006 17:21 » |
|
Алексей1153, Я даже не заметил опечатки. Тогда есть еше одна опечатка string::srting(const char* s) //Надо писать string, а не srting. { p = new srep; p->s = new char[strlen(s) + 1]; strcpy(p->s,s); }
Кстати и в определении конструктора по дефаулту, обратно этот srting.
|
|
« Последнее редактирование: 03-05-2006 17:29 от Finch »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #5 : 03-05-2006 18:03 » |
|
Finch, а это не я, это компилятор заметил
и ещё он ругается на строки friend ostream& operator <<(ostream&, const string&); friend istream& operator >>(istream&, string&);
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #6 : 03-05-2006 18:21 » |
|
У меня это решилось просто. я за место #include <iostream> поставил #include <iostream.h>.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Druid
Гость
|
|
« Ответ #7 : 03-05-2006 19:55 » |
|
Алексей1153, Я даже не заметил опечатки. Тогда есть еше одна опечатка string::srting(const char* s) //Надо писать string, а не srting. { p = new srep; p->s = new char[strlen(s) + 1]; strcpy(p->s,s); }
Кстати и в определении конструктора по дефаулту, обратно этот srting.
Упс, это невнимательность, я даже не подумал что мог просто слово не так написать (( Поправил все ошибки, подключил <iostream.h> вместо <iostream>. Под компилятором BC++ 3.1 все заработало вообще на ура, под Visual C++ выдает предупреждение "warning C4018: '<' : signed/unsigned mismatch" - "несоответствие знаков в операции '<' ". Такой вопрос, почему при замене <iostream.h> на <iostream> появляется 42 ошибки. Ведь насколько я понял <iostream> это стандартизированная версия той же <iostream.h>, да еще с большими возможностями. Почему же такое несоответствие может быть?
|
|
« Последнее редактирование: 19-12-2007 18:19 от Алексей1153++ »
|
Записан
|
|
|
|
Druid
Гость
|
|
« Ответ #8 : 03-05-2006 20:03 » |
|
Вспомнил по новому стандарту есть пространство имен std. Прописал: using namespace std; Ошибки сократились с 42 до 12
|
|
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #9 : 03-05-2006 20:09 » |
|
"warning C4018: '<' : signed/unsigned mismatch" это предупреждение говорит о том, что у тебя идет сравнение знаковой переменной с не знаковой. Могут быть проблемы в данном месте. Просто VC в этом отношении отличается от Борландовских компиляторов. Чуть другой подход. И из-за этого я ловил несколько раз глюки, когда переносил проект. И значения переменных были на границах значимости.
|
|
« Последнее редактирование: 19-12-2007 18:22 от Алексей1153++ »
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Druid
Гость
|
|
« Ответ #10 : 03-05-2006 20:18 » |
|
"warning C4018: '<' : signed/unsigned mismatch" это предупреждение говорит о том, что у тебя идет сравнение знаковой переменной с не знаковой. Могут быть проблемы в данном месте. Просто VC в этом отношении отличается от Борландовских компиляторов. Чуть другой подход. И из-за этого я ловил несколько раз глюки, когда переносил проект. И значения переменных были на границах значимости.
Интересно. Спасибо. Кстати оставшиеся 12 ошибок говорят о "ambiguous" двойной значимости практически везде где переопределил операции. не удобно пихать в сообщение большой этот код, ну да не знаю как его прицепить иначе, вот как стала выглядеть программа: #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; }
|
|
« Последнее редактирование: 19-12-2007 18:23 от Алексей1153++ »
|
Записан
|
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #11 : 03-05-2006 20:33 » |
|
Вот твой пример, который у меня компилится без ворнинга и ошибок #include <iostream.h> #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) || ((int)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; }
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #12 : 03-05-2006 20:37 » |
|
Кстати класс называть string это ходить по минному полю. Уже до тебя использовали такое название в стандартных библиотеках.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
|