2009-08-19 3 views
-3

Учитывая код в основной:Мусор Результат! C++ LinkedList

// main.cpp 
wineries->insert(winery("Lopez Island Vinyard", "San Juan Islands", 7, 95)); 

две вещи случатся:

  1. Конструктор винзавод вызывается, когда я intialized винодельни частных пользователей:

    //winery.cpp 
    winery::winery(const char * const name, const char * const location, 
           const int acres, const int rating) 
        : name(new char[strlen(name)+1]) 
        , location(new char[strlen(location)+1]) 
        , acres(0), rating(0) 
    { 
    
    } 
    

    Когда он будет завершен, результат указателя this имеет значение для мусора. Почему это? Я не правильно инициализирую?

  2. После того, как конструктор винзавод умирает, мы идем к функции list::insert(const winery &winery):

    void list::insert(const winery& winery) 
    { 
        node *NodePtr = new node(winery); 
        // NodePtr->item has the garbage. 
        NodePtr->item = winery; 
    } 
    
    list::node::node(const winery& winery) 
    { 
        // This works because I have a default constructor for the winery object 
        // and *only* for that reason... 
        // How can I use the node constructor without having to use a default constructor for the winery class? 
    } 
    

    Почему я получаю мусор в результате значений, переданных конструктору Виннице?

    винодельни функции-члены являются, где name, location, acres и rating все частные члены к классу винодельня.

    winery::winery() 
    { 
        // do nothing default constructor 
        // only here so I can add the &winery to the node constructor.. 
    } 
    
    winery::~winery() 
    { 
        delete location; 
        delete name; 
        // your code here 
    } 
    
    const char * const winery::getName() const 
    { 
        //winery *wine_t = new winery(); 
        const char cName[5] = "four"; 
        // just to see if it still gives garbage.. 
        return cName 
    } 
    
    const char * const winery::getLocation() const 
    { 
        // return one of winery's private members. 
        // It *will* crash when this function is called. 
        // *That* might be the issue with **garbage values** return location; 
    } 
    

    Без этих функций с параметрами, что делает его трудно передать атрибуты к объекту wineryPtr, и тогда было бы логично, чтобы добавить весь объект винного завода в LinkedList ...

    // list.h 
    #ifndef _LIST_ 
    #define _LIST_ 
    
    #include <ostream> 
    #include "winery.h" 
    
    using namespace std; 
    
    class list 
    { 
    public: 
        list(void);    // constructor 
        virtual ~list(void); // destructor 
        ... 
        void insert(const winery& winery); 
        winery * const find(const char * const name) const; 
    
    
    private: 
        struct node 
        { 
          node(const winery& winery);  // constructor 
         winery item; 
         node * nextByName; 
         node * nextByRating; 
         }; 
    
        node * headByName; 
        node * headByRating; 
    }; 
    
    #endif // _LIST_ 
    

Мои вопросы немного рассеяны, и я надеюсь, что у кого-то есть время, чтобы помочь!

+2

Пожалуйста, прикладывать больше усилий задавать ваш вопрос правильно. Я гарантирую, что вы получите лучший ответ –

+0

Где на земле этот указатель, о котором вы говорите? – Zed

+0

Я не понимаю, что вы имеете в виду? Что вы понимаете под мусорной ценностью, и как вы определяете, что это мусор? Покажите некоторый код, который воспроизводит проблему, включая показ того, где вы получаете данные мусора, и как вы проверяете, что это мусор. – jalf

ответ

2

Возможно, причина в том, что вам не хватает конструктора-копира и оператора = в вашем классе винзавода. Когда вы вставляете его в список, указатели имени и местоположения копируются в разные стороны, но строки, на которые они указывают, являются общими. Затем экземпляр, который вы скопировали, выходит из области видимости, и экземпляры удаляются.

В вашем отладчике поместите точку останова в конструкторе, где вы создаете name и location, а затем также в деструкторе. Вы увидите, что количество распределений не соответствует количеству деаллокаций.

+0

У меня есть копия CTOR в моем классе винодельни, а также оператор << в классе винодельни. – user40120

+0

У вас есть оператор =? –

0

Хорошо. Как-то в моем набрав я вижу немного более ясно.

Это то, что я имел в виду:

winery::winery(const char * const name, const char * const location, const int acres, const int rating): name(new char[strlen(name)+1]), location(new char[strlen(location)+1]), acres(0), rating(0) 
{ 
    strcpy_s(this->name, MAXNAME_SZ, name); 
    strcpy_s(this->location, MAXNAME_SZ, location); 
    this->acres = acres; 
    this->rating = rating; 
} 

где MAXNAME_SZ является константной INT 75.

+0

Вам по-прежнему необходимо выделить пространство для переменных-членов «имя» и «местоположение», –

2

Ваша реализация винзавод конструктор не выглядит для меня:

//winery.cpp 
winery::winery(const char * const name, const char * const location, 
       const int acres, const int rating) 
    : name(new char[strlen(name)+1]) 
    , location(new char[strlen(location)+1]) 
    , acres(0), rating(0) 
{ 
}

Во-первых, вы просто выделили память для переменных имени и местоположения, но не указали содержимое из входных параметров.

Во-вторых, вы инициировали акты и оценивали переменные-члены с нулями. Это ваше намерение?

И, наконец, вам нужно скопировать constuctor и оператор присваивания!

2

Причина многих проблем, вероятно, тот факт, что ваш узел содержит winery объекта по значению и ваш winery конструктора по умолчанию не назначая NULL к location и name. Ваша insert операция создает winery объекта, используя конструктор по умолчанию, когда он выделяет node объекта, то объект будет перезаписан, когда происходит NodePtr->item назначения. Это приводит к вызову оператора присваивания. Оператор присваивания не может быть правильно реализован без конструктора по умолчанию, который делает правильную вещь.

Я делаю некоторые предположения здесь, так как я не знаю, что list::node::node(const winery&), winery::operator=(const winery&) или winery::winery(const winery&) выглядеть, но я не могу себе представить, что они могут быть реализованы правильно, не имея winery членов устанавливается на известное значение по умолчанию ,

Я бы тщательно пройти через insert() вызов, который вы упомянули, пока вы полностью не понимаете, какие операции называют. Рассмотрим следующую программу.

#include <iostream> 

struct node { 
    node() { std::cout << "default constructor" << std::endl; } 
    node(int) { std::cout << "int constructor" << std::endl; } 
    node(node const&) { std::cout << "copy constructor" << std::endl; } 
    ~node() { std::cout << "destructor" << std::endl; } 
    node& operator=(node const&) { std::cout << "assignment" << std::endl; } 
}; 

void 
insert(node const& a) { 
    node b(a); 
    node c; 
    b = c; 
} 

int 
main() { 
    insert(node(1)); 
    return 0; 
} 

запустить его и посмотреть, если вы можете следовать, почему выход:

int constructor 
copy constructor 
default constructor 
assignment 
destructor 
destructor 
destructor 

Вы проблема заключается в том, что ваш конструктор по умолчанию, конструктор копирования и операторы присваивания не делать правильные вещи. Надеюсь, это приведет вас к правильному пути.