1

次のコードを見てください

Location.h

#pragma once
class Location
{
public:
    Location(void);
    Location(int,int,int);
    ~Location(void);
    Location(const Location *loc);

    void display();
    void set(int,int,int);

private:

    int x,y,z;
};

ロケーション.cpp

#include "Location.h"
#include <iostream>
#include <string>

using namespace std;


Location::Location()
{
}

Location::Location(int x,int y, int z)
{
    set(x,y,z);
}



Location::~Location(void)
{
}


void Location::display()
{
    cout << "X: " << x << endl;
    cout << "Y: " << y << endl;
    cout << "Z: " << z << endl;
}

void Location::set(int xx,int yy,int zz)
{
    x = xx;
    y = yy;
    z = zz;
}

Object.h

#pragma once
#include "Location.h"

class GameObject
{
public: 
    GameObject(int);
    ~GameObject(void);
    GameObject(int,Location *);
    GameObject(const GameObject *obj);

    Location *location;

    int getNumberOfObjects();

    static int counter;


    int id;

private:
    GameObject(void);



};

オブジェクト.cpp

#include "GameObject.h"
#include <iostream>

using namespace std;

static int counter = 0;

int GameObject::counter = 0;

GameObject::GameObject(void)
{
}

GameObject::GameObject(int i)
{
    counter++;
    id = i;
}

GameObject::GameObject(int i,Location *loc)
{
    id = i;
    location = loc;
}

GameObject::GameObject(const GameObject *ob)
{
    this->location = new Location(ob->location);
}


GameObject::~GameObject(void)
{
}

メイン.cpp

#include <iostream>
#include "GameObject.h"

using namespace std;

int main()
{
    //GameObject obj1;
    //cout << obj1.id << endl;

    GameObject obj2(45);
    cout << obj2.id << endl;;
//  cout << obj2.counter << endl; 

    //Declaring dynamic objects for Location
    Location *loc1 = new Location(1,1,1);
    Location *loc2 = new Location(2,2,2);
    Location *loc3 = new Location(3,3,3);


    //Assigning each GameObject a location
    GameObject obj3(45,loc1);
    GameObject obj4(45,loc2);
    GameObject obj5(45,loc3);

    //Displaying Number of GameObject objects
    cout << "Number of Objects: " << GameObject::counter << endl;

    //Invoking Location's display() method using GameObject objects
    cout << "......obj3 values........" << endl;
    obj3.location->display();
    cout << "......obj4 values........" << endl;
    obj4.location->display();
    cout << "......obj5 values........" << endl;
    obj5.location->display();


    //Declaring new Static GameObject
    GameObject obj6(obj4);

    //Invoking display() member function using both obj4 and obj6 GameObjects
    cout << endl;
    cout << "Invoking display() member function using both obj4 and obj6 GameObjects " << endl;
    obj4.location->display();
    obj6.location->display();

    //Changing the location values in obj4
    obj4.location->set(8,8,8);

    //Invoking display() member function using both obj4 and obj6 GameObjects
    cout << endl;
    cout << "Invoking display() member function using both obj4 and obj6 GameObjects " << endl;
    obj4.location->display();
    obj6.location->display();




    system("pause");
    return 0;
}

ここでは、Main.cpp でわかるように、obj4 の「場所」が変更されるとすぐに、obj6 の「場所」が変更されています。obj4 の場所を変更するときに、obj6 の「場所」を変更したくありません。

これを実行すると、このエラーが発生します

GameObject.obj : error LNK2019: unresolved external symbol "public: __thiscall Location::Location(class Location const *)" (??0Location@@QAE@PBV0@@Z) referenced in function "public: __thiscall GameObject::GameObject(class GameObject const *)" (??0GameObject@@QAE@PBV0@@Z)

ディープコピーコンストラクターでやろうとしましたが、うまくいきませんでした。助けてください。

4

5 に答える 5

4
GameObject::GameObject(const GameObject *ob)

はコピー コンストラクターではありません。次のものが必要です。

GameObject::GameObject(const GameObject &ob)
                                       ^^^

また、ディープ コピーを 行うコピー代入演算子を提供する必要があります。

理想的な解決策は、生のポインターではなくスマート ポインターをメンバーとして使用することです。
これにより、基本的にディープコピーのすべての手間が省けます。


よく読んでください:
3つのルールとは何ですか?

于 2012-12-06T05:57:02.553 に答える
3

tl;dr変換 cnstructorの代わりにコピー コンストラクターを実装してみてください。

//this
GameObject(const GameObject &obj);
//instead of this
GameObject(const GameObject *obj);
于 2012-12-06T05:56:18.457 に答える
2

C++ では、オブジェクトをヒープ上に作成でき、それらのメモリ アドレスはポインターに格納されます。オブジェクトはスタック上に作成することもでき、参照によって示すことができます。

コピー コンストラクターを定義するときは、ポインターの代わりに参照を使用する必要があります。その理由は、コピー コンストラクターでポインターを使用すると、ヒープ内の同じオブジェクトを指す 2 つのポインターが作成されるためです。したがって"obj6""obj4"メモリ内の同じオブジェクトへのポインタです。

于 2012-12-06T06:56:24.957 に答える
2

まず、他の人が指摘したように、コピー コンストラクターを実装していません。

GameObject::GameObject(const GameObject *ob)

これは、const GameObject へのポインターを取る関数です。コピー コンストラクターは、作成元のオブジェクトへの const 参照を取る必要があります。

GameObject::GameObject(const GameObject &ob)

しかし、私は別の問題も見ています。本当にディープ コピーが必要な場合は、Location オブジェクトを分離し、一方を変更しても他方に影響を与えないようにする必要があります。これを考えると、単純な Location メンバーではなく、GameObject が Location へのポインターを保持する必要がある理由がわかりません。したがって、これを変更し、イニシャライザ リストを使用して場所を指定された場所のコピーにするコピー コンストラクタを作成することをお勧めします。

これを GameObject ヘッダーに入れます。

class GameObject
{
public: 
    GameObject(int);
    ~GameObject(void);
    GameObject(int,const Location&);
    GameObject(const GameObject &obj);

    Location location;

    int getNumberOfObjects();

    static int counter;


    int id;

private:
    GameObject(void);
}

コンストラクタを次のように記述します。

GameObject(int i)
: id(i)
{}

// This will cause GameObject to be uninitialized
~GameObject(void)
{}

GameObject(int i,const Location& loc)
: id(i), location(loc)
{}

GameObject(const GameObject &obj)
: id(obj.id), location(obj.location)
{}

最後に、同じロジックを使用して、シグネチャを持つ適切な Location コピー コンストラクターを構築する必要があります。

Location(const Location &loc);

その実装は、読者の演習として残しておきます。;)

また、いくつかのコメント (実際には静的ではないメンバーの上の「静的」コメントなど) を読むと、C++ でのメモリ管理についてもう少し読みたいと思うかもしれません。:) 「C++ フリー ストア」で少し Google を検索してください。ヒントは、必要のない場所では動的メモリを使用しないことです。C++ では、すべてのオブジェクトを で作成する必要はありませんnew

于 2012-12-06T06:40:10.437 に答える
1

Location オブジェクトのコピー コンストラクターの実装がないようです。メソッド Location(const Location* loc) を実装するとすぐに問題が解決されると思います。

Location(const Location* loc) {
   this->x = loc->x;
   this->y = loc->y;
   this->z = loc->z;
}
于 2012-12-06T06:32:32.103 に答える