По умолчанию Перегрузка операторов ввода и вывода из потоков.

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Hixon, 17 Oct 2011.

  1. Hixon

    Hixon Member

    Joined:
    17 Apr 2010
    Messages:
    88
    Likes Received:
    9
    Reputations:
    0
    Перегрузка операторов ввода и вывода из потоков.

    Добрый день. Была лаба, которую я успешно сдал, но появился один момент, который я не понял. Задание - создать некое подобие класса fstream, перегрузив операторы ввода и вывода из потока. То есть, записывая такой код:
    Code:
    class1 obj1;
    obj1.open("text.txt");
    obj1<<"test";
    
    Строка ТЕСТ записывается в файл, с вторым оператором все аналогично.
    Операторы я перегрузил, но, как мне кажется, они работают не полноценно. При использование такого кода:
    Code:
    class1 obj1;
    obj1.open("text.txt");
    obj1<<"test"<<4;
    
    Появляется ошибка. В принципе, это и логично, так как я неверно работаю с потоком (беру информацию из него, а возвращаю - void). Как работать с ними, потоками, верно?
    Code:
    #include <conio.h>
    #include <iostream.h>
    #pragma hdrstop
    
    class myFile {
     protected:
     static FILE *pFile;
    
     public:
     myFile () {}
    };
    
     FILE *myFile::pFile;
    
    class myFileR: virtual public myFile {
     public:
     myFileR (char *p): myFile () {
    		pFile = fopen (p,"r");
     }
     myFileR (): myFile () {}
     void open (char *d) {
    		pFile = fopen (d,"r");
     }
     void close (void) {
    		fclose (pFile);
     }
    int operator >>(int &y) {
    		if (!pFile) exit(0);
    		fscanf(pFile,"%d",&y);
     }
    
     void operator >>(char *y) {
    		if (!pFile) exit(0);
    		fgets (y, 100, pFile);
     }
    };
    
    
    class myFileW: virtual public myFile {
     public:
     myFileW (char *p): myFile () {
    		pFile = fopen (p,"a");
     }
     myFileW (): myFile () {}
     void open (char *d) {
            if (pFile) fclose (pFile);
            pFile = fopen (d,"a");
     }
     void close (void) {
            fclose (pFile);
     }
     void operator <<(int y) {
            if (!pFile) exit(0);
            fprintf(pFile,"%d",y);
     }
     void operator <<(double y) {
    		if (!pFile) exit(0);
            fprintf(pFile,"%g",y);
     }
     void operator <<(float y) {
            if (!pFile) exit(0);
            fprintf(pFile,"%f",y);
     }
     void operator <<(char y) {
            if (!pFile) exit(0);
            fprintf(pFile,"%c",y);
     }
     void operator <<(char *y) {
            if (!pFile) exit(0);
            fprintf(pFile,"%s",y);
     }
    };
    
    
    class myFileA: public myFileR, public myFileW {
     public:
     //myFileA
    };
    
    int main() {
      int m=5;
     char *p = new char [80];
    
     myFileW a;
     a.open("G:\\fewrfw.txt");
     a<<"erge";
     a<<5;
     a.close();
    
    
     myFileR b("G:\\fewrfw.txt");
     b>>p;
     cout<<p;
     getch();
    }
     
    #1 Hixon, 17 Oct 2011
    Last edited: 17 Oct 2011
  2. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    1. Вынести оператор << за пределы класса.
    2. Возвращать принимаемый первым параметром поток ввода-вывода (точнее, ссылку на него).

    Достаточно глянуть на исходники stl или немного погуглить
     
  3. Hixon

    Hixon Member

    Joined:
    17 Apr 2010
    Messages:
    88
    Likes Received:
    9
    Reputations:
    0
    Не поверите, но я это делал. Конечно же, находил "правильный" прототип перегрузки cout:
    Code:
    friend ostream& operator<<(ostream&, const Int&);
    friend istream& operator>>(istream&, Int&);
    
    Прототип работает, если я принимаю вторым параметром пользовательский тип, а вот если принимать что-то стандартное (инт, флоат и т.д.), то пишет ошибку (мол уже переопределен данный оператор).

    Из теории: если мы выносим перегрузку оператора в глобальную память, то нужно принимать, хотя бы один пользовательский класс. Какой принимать мне? Свой? Если да, то программа не работает. Пробовал и с дружественной функцией играться, опять же ничего не вышло.
    Не могли бы вы дать один пример для перегрузки >> или <<, который будет корректно работать для моего случая?
    Спасибо.
     
  4. GRRRL Power

    GRRRL Power Elder - Старейшина

    Joined:
    13 Jul 2010
    Messages:
    823
    Likes Received:
    185
    Reputations:
    84
    PHP:
    #include <iostream>
    #include <string>

    //некий класс, представляющий возможности потоков
    class some_ostream
    {
    public:
        
    void out(const std::stringstr)
        {
            
    //тут что-то делаем с str
            
    std::cout << "From class [string]: " << str << std::endl;
        }

        
    void out(int val)
        {
            
    //тут что-то делаем с val
            
    std::cout << "From class [int]: " << val << std::endl;
        }
    };

    some_ostreamoperator<<(some_ostreamstream, const std::strings)
    {
        
    stream.out(s);
        return 
    stream;
    }

    some_ostreamoperator<<(some_ostreamstreamint i)
    {
        
    stream.out(i);
        return 
    stream;
    }


    int main()
    {
        
    some_ostream s;
        
    << "Hello, world" << 123;
        return 
    0;
    }
     
  5. Hixon

    Hixon Member

    Joined:
    17 Apr 2010
    Messages:
    88
    Likes Received:
    9
    Reputations:
    0
    GRRRL Power, спасибо! Сейчас попробую осознать это, и переложить на свой код.