2013-05-25 7 views
2

Я пытаюсь изучить стандартную библиотеку в C++, и я пытаюсь запустить свой код, но я не могу добиться успеха. Что я забыл и что мне нужно добавить в мой класс «Класс», чтобы программа работала так, как должна?Использование стандартной библиотеки в C++, алгоритм копирования

#include <iostream> 
    #include <vector> 
    #include <list> 
    #include <algorithm> 
    #include <iterator> 
    using namespace std; 

    class Class { 
    public: 
     Class (int ii, double dd) : ival(ii) { dval = new double; *dval = dd; } 
     ~Class() { delete dval; } 
    private: 
     int ival; 
     double *dval; 
    }; 

    int main() 
    { 

     vector<Class> vec; 
     list<Class> list; 
     vec.push_back(Class(1, 2.2)); 
     vec.push_back(Class(2, 4.3)); 
     vec.push_back(Class(3, 5.7)); 
     ostream_iterator<const Class> classout(cout,"\n"); 
     copy(vec.begin(), vec.end(), classout); 
    } 

Я в основном пытается понять и использовать копировальную-алгоритм:

template 
     OutputIterator copy (InputIterator first, InputIterator last, 
          OutputIterator result) 
    { 
     while (first!=last) *result++ = *first++; 
     return result; 
    } 
+0

@codesinchaos может быть, вы можете мне помочь? :) – Stabbah

ответ

1

std::ostream_iterator использует оператор вставки << для вставки объектов в выходной поток. Вы должны предоставить такого оператора. Пример реализации с использованием функции-члена:

class Class { 
public: 
    Class (int ii, double dd) : ival(ii) { dval = new double; *dval = dd; } 
    ~Class() { delete dval; } 
    void print(std::ostream &stream) const { 
    stream << ival << ' ' << *dval; 
    } 
private: 
    int ival; 
    double *dval; 
}; 

std::ostream& operator<< (std::ostream &stream, const Class &arg) { 
    arg.print(stream); 
    return stream; 
} 

В качестве альтернативы можно также осуществить его, сделав его friend и не создает функцию-член.

+0

Спасибо, ребята, за помощь! @Angew – Stabbah

1

У вашего кода есть несколько проблем. Первое, что должно привести к ошибке компиляции, заключается в том, что ваш класс не объявляет оператор << для потоковой передачи, что означает, что его нельзя распечатать в потоке, используя ostream_iterator. Чтобы исправить это, вам нужно добавить такой оператор в класс, например:

class Class { 
public: 
    Class (int ii, double dd) : ival(ii) { dval = new double; *dval = dd; } 
    ~Class() { delete dval; } 
    friend std::ostream& operator<<(std::ostream& os, const Class& c) 
    { 
    return os<<c.ival<<": "<<*c.dval;//or whatever you want your output to look like 
    } 
private: 
    int ival; 
    double *dval; 
}; 

Однако ваш код содержит еще одну серьезную проблему: нарушение правила трех (или пяти/независимо, если вы находитесь на с ++ 11). Ваш класс объявляет пользовательский деструктор, но не собственный конструктор копирования или пользовательский оператор присваивания. Это означает, что когда вы копируете экземпляр своего класса (например, помещаете его в vector, оба объекта будут содержать один и тот же указатель, что приведет к ошибке времени выполнения из-за двойного освобождения от уничтожения второго объекта. нужно объявить эти операции самостоятельно или (даже лучше) сами не выполнять управление ресурсами, но вместо этого использовать интеллектуальные указатели (C++ 11 std :: unique_ptr или std::shared_ptr, std::tr1::shared_ptr или указатель от boost для простого кода C++ 11)