2012-09-13 2 views
1

Я изучаю C++ и предлагаю проект класса через 5 дней. Я провел 4 часа, исследуя, как это сделать, но я еще не получил ответа. Сохраните стек!C++ overload pointer ostream

Проблема. У меня есть указатель на класс, который содержит динамический массив. Мне нужно взять этот массив и сохранить его в файл для последующего извлечения. Вот мои 2 заголовка и реализация. Я не пишу код для сохранения в файл, но это будет легко, когда я обойду эту проблему. Моя проблема заключается в том, что он печатает адрес указателя, а не данные внутри.

vehReg.h

class vehReg { 
    public: 
     /* STUFF */ 
    }; 
} 
#endif 

vehData.h

#include "vehReg.h" 

using namespace std; 

class vehData { 
    public: 
     //CONSTRUCTORS 
     vehData(); 

     //DECONSTRUCTOR 
     ~vehData(); 

     //METHODS 
     friend ostream &operator<<(ostream &output, const vehData &v); 

    private: 
     typedef unsigned long longType; 
     typedef std::size_t sizeType; 
     sizeType used,capacity; 
     vehReg *data; 
    }; 
} 
#endif 

vehData.cpp

//CONSTRUCTOR 
    vehData::vehData(){ 
     capacity = 5; 
     used = 0; 
     data = new vehReg[capacity]; 
    } 

    //DECONSTRUCTOR 
    vehData::~vehData(){ 
     delete []data; 
    } 

    /* TRYING TO ACCOMPLISH THIS WITH AN OSTREAM OVERLOAD */ 
    void vehData::saveDataSloppy(){ 
     ofstream myFile; 
     myFile.open ("database.db"); 
     for(int i=0;i<used;i++){ 
      myFile << data[i].getOwnerName() << "|"; 
      myFile << data[i].getVehicleLicense() << "|"; 
      myFile << data[i].getVehicleMake() << "|"; 
      myFile << data[i].getVehicleModel() << "|"; 
      myFile << data[i].getVehicleYear() << "\n"; 
     } 
     myFile.close(); 
} 

    void vehData::saveData(){ 
     cout << data; 
    } 

    ostream &operator<<(ostream &stream, const vehData &v){ 
     stream << v.data; 
    } 
} 
+0

Это главный кандидат на [sscce] (http://sscce.org). Ответ на то, почему он печатает адрес, лежит в основе самих указателей, и я уверен, что вы узнали, что у вас есть задание, сосредоточенное вокруг них. – chris

+0

«он печатает адрес указателя, а не данные внутри», возможно, вы могли бы дать нам представление о том, что здесь означает «это»? Я просмотрел (слишком длинный) код и не подозревал. Как предлагает @chris, сократите его до самого простого примера, который вы можете создать, который компилирует, запускает и иллюстрирует проблему. Если это не показывает вам, что происходит не так, разместите сокращенную версию кода с описанием того, что вы ожидаете от этого, и тем, что он на самом деле делает. –

+0

@PeteBecker, это перегруженный 'operator <<' print' v.data', который является указателем. Я бы сказал, [это] (http://liveworkspace.org/code/cce76ba541a348c700fd057e9e676595) является хорошим примером sscce, который реплицирует проблему, которую вы имеете. Конечно, как намекнул мой первый комментарий о том, что проблема заключается в самих указателях, вам даже не понадобится структура для возникновения проблемы. – chris

ответ

2

v.data является указатель, поэтому он печатает указатель. Как вы хотите, чтобы он печатал все, на что указывает указатель. За исключением символов указателей, << всегда печатает то, что вы ему даете (отформатировано в некотором способе). Если вы не хотите, чтобы он печатал указатель, дайте что-то еще.

Предположим, что он сделал разыменование указателя. Что он должен печатать: один vehReg? 20? Указатель не имеет информации о размере. Если бы вы использовали std::vector<vehReg> (намного лучший выбор), он будет знать, размера, но до сих пор нет перегрузки на std::vector, так как система до сих пор не знает, как вы хотите его отформатирован (разделенную запятая? каждый на новая строка?). И вы не сказали, как распечатать vehReg .

Вы, по-видимому, понимаете, как перегружать <<. Первое, что вам нужно сделать, это перегрузка vehReg. И обе перегрузки должны быть определены с точки зрения существующих перегрузок: там нет ни одного для std::vector, а один для указателя не делает то, что вы хотите (и не можете), поэтому вам нужно будет зациклиться на << для vehData и выводить каждый элемент, с любыми разделителями, которые вы принимаете . (Если это каждый элемент в отдельной строке, то вы можете использовать std::copy и ostream_iterator для цикла, но это может быть немного заранее того, что вы узнали до сих пор.) И перейдите на << для vehReg для каждый vehReg.

+0

Мы еще не научились векторам :( –

+0

@TimHibbard, они представляют собой динамические массивы, которые управляют вами и совместно используют общий интерфейс с другими контейнерами. – chris

+0

Я думаю, я могу сделать следующее, чтобы это стало проще. я пытаюсь выполнить. –

0

v.data - указатель, поэтому это адрес памяти.

*v.data - это то, на что указывает указатель (который в этом случае является целым числом).

Например,

#include <iostream> 

using namespace std; 

void main() { 
int *ptr; 
int var = 5; 
ptr = &var; 
cout << ptr << endl; 
cout << *ptr << endl; 
system("pause"); 
} 

Первая строка напечатает что-то вроде: 0043F930

Вторая строка напечатает: 5

Это должно вывести из элементов, проведенных в массиве данных.

void vehData::showStructure() const { 
    for (int i = 0; i < capacity: i++) { 
     cout << data[i]; 
    } 
    cout << endl; 
}