На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Отличие iostream от iostream.h ???
    Доброго времени суток. я тут в процессе обучения реализовал пример из Страуструпа и наткнулся на проблему, пример работает только при подключенной строке

    ExpandedWrap disabled
      #include <iostream.h>


    а при

    ExpandedWrap disabled
      #include <iostream>

    не хочет работать ((

    Почему не хочет никак не пойму, я думал эти библиотеки практически одинаковые, только iosrteam стандартизована...

    Вот код программы, реализован под Visual C++ 6.0:

    ExpandedWrap disabled
      #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;
      }
      Кажется в iostream.h по умолчанию используется пространство имен std.
      Если не прав поправьте..
        Цитата Druid @
        Почему не хочет никак не пойму, я думал эти библиотеки практически одинаковые, только iosrteam стандартизована...

        В iostream.h все классы объявлены в глобальном пространстве имен, а в iostream - в пространстве std. По этому при использовании iostream тебе надо либо в начале файла указать \
        using namespace std;

        либо перед каждым упоминанием имени из iostream ставить std::
          А какой у тебя компилятор ? похоже борланд, так он в <iostream.h> делает include stlport\iostream и потом using namespace std;

          Цитата Flex Ferrum @
          В iostream.h все классы объявлены в глобальном пространстве имен,
          :no: , там просто include
            Так в примере при замене библиотеки с <iostream.h> на <iostream> еще и прописывается строка

            ExpandedWrap disabled
              using namespace std;


            Без нее компилятор выдает вообще 42 ошибки ))
            Он при смене библиотеки начинает придираться к перегрузке операций почему-то...
              Цитата Druid @
              Он при смене библиотеки начинает придираться к перегрузке операций почему-то...

              В таком случае ошибки и код в студию.
                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)

                Ошибки почти везде где есть перегрузка операций
                  Тема много раз обсасывалась:
                  Глюки using namespace std
                  Функция друг
                  Друзья
                    Спасибо за ссылки, сейчас почитаю...
                      1. К чему тут объявлен класс string?
                      2. В данном примере, если хочется оставить свой класс string, можно внести его в свое простанство имен:
                      ExpandedWrap disabled
                        #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;
                        }
                        <iostream> - это по новому стандарту. Раньше было <iostream.h>

                        Что касается using-определений, рекомендуется подключать только необходимые в проекте классы/функции, чтобы не потревожить внутренности STL. Что ты и сделал, переопрелив стандартный класс string :wacko:
                          Чтобы не потревожить внутренности, надо создавать свое пространство имен(namespace)
                            Переименовал класс и все с ним связанное из string в string_my ошибки уменьшились. Поместил новый класс string_my в новое пространство имен my и ошибки исчезли совсем.

                            А как теперь обращаться к функциям-членам из функции main()

                            ExpandedWrap disabled
                              my::string_my::<нужная функция>

                            ?
                            Указывать сперва пространство, потом имя класса, если их несколько в моем пространстве имен, а потом нужную мне функцию?
                              Цитата Druid @
                              А как теперь обращаться к функциям-членам из функции main()?

                              <имя объект>-><имя функции> или <имя объект>.<имя функции>.
                              ExpandedWrap disabled
                                my::A a;
                                a.f();
                              Сообщение отредактировано: kalexs_uzb -
                                Есть еще вопрос не по созданной теме, но по приведенному примеру.
                                Когда операторную функцию нужно определять как функцию-член, а когда как глобальную с описанием Friend ???
                                  Цитата
                                  Переименовал класс и все с ним связанное из string в string_my ошибки уменьшились. Поместил новый класс string_my в новое пространство имен my и ошибки исчезли совсем.


                                  Если не ошибаюсь, просто в <iostream> уже есть свой класс string
                                    Цитата kalexs_uzb @
                                    <имя объект>-><имя функции> или <имя объект>.<имя функции>.
                                    ExpandedWrap disabled
                                      my::A a;
                                      a.f();

                                    то есть пространство имен указывается один раз при вызове кноструктора, а потом к объекту можно обращаться как обычно?
                                      Цитата Druid @
                                      то есть пространство имен указывается один раз при вызове кноструктора, а потом к объекту можно обращаться как обычно?

                                      следи за определениями:
                                      в какой области объявлен класс A? В my, значит пишем my::A
                                      в какой области объявлен объект a? В общей, значит пишем a

                                      Советую почитать Страуструпа
                                        Так пример из Страуструпа и есть :)

                                        Спасибо всем за помощь )
                                        1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                        0 пользователей:


                                        Рейтинг@Mail.ru
                                        [ Script execution time: 0,0451 ]   [ 15 queries used ]   [ Generated: 2.10.25, 20:11 GMT ]