2016-06-24 5 views
-3

Итак, я пытаюсь написать программу, которая отслеживает различные атрибуты винных заводов, которые имеют следующие атрибуты.Как использовать целые числа и поплавки внутри объекта правильно?

-Dynamically распределяемой памяти

-целых следить за год винзавод начал

-Floats для рейтинга успеха и акрах земли виноградников принять.

-Функции для добавления, удаления, отображения (по рейтингу и по имени) и сохранения данных винодельни.

Я уже написал/отладил код для работы с аналогичной программой, где все атрибуты были cstrings, и этот код основан на одной и той же структуре.

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

Может ли кто-нибудь указать, что я делаю неправильно? Я не знаю, как я вернусь через параметры, если определение int и floats aWinery не было указателем. Единственные примеры программирования динамической памяти, которые я могу найти в классах, используют cstrings. Я отметил пару пунктов в коде, который я скопировал у инструктора, потому что я не мог понять это.

EDIT: конкретная ошибка, которую я получаю, равна invalid conversion from int* to int\n year = this->year, которая имеет некоторую перестановку во всех целых числах aWinery и аксессуарах и функциях мутатора на основе float.

Список Accessor, Mutator, конструктор, и деструктор функции

void list::getWineryLocation(char location[]) const 
{ 
    wineryData.getLocation(location); 
} 

void list::getWineryYear(int year) const 
{ 
    wineryData.getYear(year); 
} 

void list::getWineryAcres(float acres) const 
{ 
    wineryData.getAcres(acres); 
} 

void list::setWineryLocation(char location[]) 
{ 
    wineryData.setLocation(location); 
} 

void list::setWineryYear(int year) 
{ 
    wineryData.setYear(year); 
} 

void list::setWineryAcres(float acres) 
{ 
    wineryData.setAcres(acres); 
} 

//Constructor functions 

list::list() 
{ 
    nameHead = NULL; 
    nameTail = NULL; 
    ratingHead = NULL; 
    ratingTail = NULL; 
    size = 0; 
} 

//Destructor 
//Doesn't delete the head/tailRating pointers to avoid double deleting a winery 
list::~list() 
{ 
    node * curr = nameHead; 

    while (nameHead != NULL) 
    { 
     curr = nameHead->nextByName; 

     delete nameHead; 

     nameHead = curr; 
    } 
} 

aWinery Accessor, мутаторный, конструкторы и функции Destructor заголовка

//Winery object constructor 
aWinery::aWinery() 
{ 
    name = new char[strlen("Unknown")+1]; 
    strcpy(name, "Unknown"); 
    location = new char[strlen("Unknown")+1]; 
    strcpy(location, "Unknown"); 
    year = new int; 
    year = 0; 
    acres = new float; 
    acres = 0; 
    successRating = new float; 
    successRating = 0; 
} 

//I have no idea whats going on here 
//Winery destructor 
aWinery::~aWinery() 
{ 
    if(name != NULL) 
     delete [] name; 
    if(location != NULL) 
     delete [] location; 
    if(year != 0) 
     delete year; 
    if(acres != 0) 
     delete acres; 
    if(successRating != 0) 
     delete successRating; 
} 

void aWinery::getLocation(char location[]) const 
{ 
    strcpy(location, this->location); 
} 

void aWinery::getYear(int year) const 
{ 
    year = this->year; 
} 

void aWinery::getAcres(float acres) const 
{ 
    acres = this->acres; 
} 

//I have no idea why this is written this way, I copied this from an instructor example 
void aWinery::setLocation(char location0[]) 
{ 
    if(this->location != NULL) 
     delete [] this->location; 
    this->location = new char[strlen(location0)+1]; 

    strcpy(this->location, location0); 
} 

void aWinery::setYear(int year0) 
{ 
    if(this->year != 0) 
     delete this->year; 
    this->year = new int; 

    this->year = year0; 
} 

void aWinery::setAcres(float acres0) 
{ 
    if(this->acres != 0) 
     delete this->acres; 
    this->acres = new float; 

    this->acres = acres0; 
} 

заголовочный файл aWinery

#ifndef AWINERY_H 
#define AWINERY_H 

#include <iostream> 
using namespace std; 

//winery object 
class aWinery 
{ 
public: 
    //Constructor 
    aWinery(); 

    //Destructor 
    ~aWinery(); 

    //Accessor Prototypes 
    void getName(char name[]) const; 
    void getLocation(char location[]) const; 
    void getYear(int year) const; 
    void getAcres(float acres) const; 
    void getSuccessRating(float successRating) const; 

    //Mutator Prototypes 
    void setName(char name0[]); 
    void setLocation(char location0[]); 
    void setYear(int year0); 
    void setAcres(float acres0); 
    void setSuccessRating(float successRating0); 


private: 
    char* name; 
    char* location; 
    int* year; 
    float* acres; 
    float* successRating; 
}; 

#endif 

список файл

#ifndef ALIST_H 
#define ALIST_H 

#include <iostream> 
using namespace std; 

const int MAX_CHAR_LENGTH = 1000; 

class list 
{ 
public: 
    //Prototypes 
    void setInWinery(char name[], char location[], int year, float acres, float successRating); 
    void initializeDbase(char savePathName[]); 
    void printEntireDbase(); 
    void deleteWinery(char nameOfWinery[]); 
    void whereIsWinery(char nameOfWinery[]); 
    void save(char savePathName[]); 

    //Accessor Prototypes 
    void getWineryName(char name[]) const; 
    void getWineryLocation(char location[]) const; 
    void getWineryYear(int year) const; 
    void getWineryAcres(float acres) const; 
    void getWinerySuccessRating(float successRating) const; 
    int getSize() const; 

    //Mutator Prototypes 
    void setWineryName(char name[]); 
    void setWineryLocation(char location[]); 
    void setWineryYear(int year); 
    void setWineryAcres(float acres); 
    void setWinerySuccessRating(float successRating); 

    //Constructor Prototype 
    list(); 

    //Destructor 
    ~list(); 

private: 
    //Wine object 
    struct node 
    { 
     aWinery wineryData; 
     node * nextByName; 
     node * nextByRating; 
    }; 
    node * nameHead, * nameTail, * ratingHead, * ratingTail; 

    aWinery wineryData; 

    int size; 
}; 

#endif 
+2

«Может кто-то указать на то, что я делаю не так? " - Возможно, курс? Ваш преподаватель не должен учить вас распределять собственные массивы символов, использовать strlen/strcpy и т. Д. - использовать 'std :: string'. Лучше не смешивать функциональность списка с вашими типами данных - делайте одно хорошо, и вы можете самостоятельно их протестировать и понять, а затем повторно использовать. 'std :: list' уже имеет хорошие списки. Не используйте 'int *' и 'float *' для хранения отдельных значений: просто сохраните их напрямую по значению. Наконец, для этого сайта - задайте * сфокусированные * вопросы по конкретной технической проблеме, перейденные в пример с коротким кодом. –

+0

@TonyD Если бы у меня была копейка за каждый раз, когда кто-то сказал мне, что курс/школа/учитель глупо. У меня было бы много лотов. Они явно лучше, но у меня нет выбора во многих вопросах. Я буду задавать более мелкие вопросы в будущем, спасибо. –

ответ

4

Я думаю, что большая часть вашей проблемы в заголовке, здесь:

private: 
    char* name; 
    char* location; 
    int* year; 
    float* acres; 
    float* successRating; 

Там действительно нет оснований использовать указатели для любого из этих переменных-членов; вы можете также сделать их все набившие оскомину элементы по значению, например:

private: 
    std::string name; 
    std::string location; 
    int year; 
    float acres; 
    float successRating; 

Обратите внимание, что я заменил (символ *) переменных-членов с станд :: строки, так как в C++ программа есть на самом деле нет причина не использовать правильный строковый объект.(Использование динамически выделенных массивов символов для хранения символьных строк может быть необходимым злом, если вы пишете на C, но на C++ это просто мазохизм)

Сохраняя все ваши данные по значению, вы можете избавиться от всех команд new и delete (и неизбежные ошибки и неэффективность, которые приходят с ними) и просто устанавливают и получают значения непосредственно, когда это необходимо.

Кроме того, эта функция аксессор неправильно:

void aWinery::getYear(int year) const 
{ 
    year = this->year; 
} 

Это не будет работать, так как в C++, параметры метода (по умолчанию) передаются по значению (т.е. временная локальная копия передается в стоимости , для использования этого метода), так что все вышеописанный метод изменяет локальный параметр year, который сразу же уничтожается, как только функция возвращается. Правильный метод сбруя будет выглядеть следующим образом:

int aWinery::getYear() const 
{ 
    return this->year; // assuming year member variable is now of type int 
} 

.... а так же, метод сеттер должен выглядеть следующим образом:

void aWinery::setYear(int newYear) 
{ 
    this->year = newYear; // assuming year member variable is now of type int 
}