-3

メインのコードを考えると:

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

次の 2 つのことが起こります。

  1. ワイナリー コンストラクターは、ワイナリーのプライベート メンバーを初期化した場所で呼び出されます。

    //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で、locationacres、および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 オブジェクトに転送することが難しくなり、ワイナリー オブジェクト全体をリンクリストに追加するのが論理的になります...

    // 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_
    

私の質問は少し散らばっています。誰かが助けてくれることを願っています!

4

4 に答える 4

2

おそらくその理由は、ワイナリー クラスに copy-constructor と operator= が欠けているためです。リストに挿入すると、名前と場所のポインターがコピーされますが、それらが指している文字列は共有されます。次に、コピー元のインスタンスが範囲外になり、インスタンスが削除されます。

デバッガーで、nameandを作成するコンストラクターにブレークポイントを配置しlocation、さらにデストラクターにもブレークポイントを配置します。割り当ての数が割り当て解除の数と一致していないことがわかります。

于 2009-08-19T00:19:32.493 に答える
2

あなたのワイナリー コンストラクターの実装は、私には適切ではありません。

//ワイナリー.cpp
winery::winery(const char * const name, const char * const location,
               const int エーカー、const int レーティング)
  : name( new char[strlen(name)+1] )
  , location( new char[strlen(location)+1] )
  、エーカー( 0 )、評価( 0 )
{
}

まず、名前と場所のメンバー変数にメモリを割り当てましたが、入力パラメーターからコンテンツを srtcpy しませんでした。

次に、ゼロでエーカーと格付けのメンバー変数を開始しました。それはあなたの意図ですか?

最後に、コピー コンストラクターと代入演算子が必要です。

于 2009-08-19T00:48:38.410 に答える
2

多くの問題の原因はおそらく、ノードにwinery値によるオブジェクトが含まれており、デフォルトのコンストラクターがandにwinery割り当てNULLられていないという事実です。あなたの操作は、オブジェクトを割り当てるときにデフォルトのコンストラクターを使用してオブジェクトを作成しており、割り当てが発生するとオブジェクトは上書きされます。これにより、代入演算子が呼び出されます。代入演算子は、既定のコンストラクターが正しく動作しないと正しく実装できません。locationnameinsertwinerynodeNodePtr->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

あなたの問題は、デフォルトのコンストラクター、コピーコンストラクター、および代入演算子が正しいことをしていないことです。うまくいけば、これがあなたを正しい道へと導きます。

于 2009-08-19T00:54:31.823 に答える
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 は 75 の const int です。

于 2009-08-19T00:45:09.470 に答える