C++ 深度复制构造函数中的问题
请看一下下面的代码 位置.hC++ 深度复制构造函数中的问题,c++,visual-studio-2010,pointers,constructor,C++,Visual Studio 2010,Pointers,Constructor,请看一下下面的代码 位置.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; }; #pragma once #in
#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;
};
#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 "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;
}
#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)
{
}
#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;
}
Object.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;
}
#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)
{
}
#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;
}
我试图用一个深度复制构造函数来实现它,但没有成功。请帮忙。tl;dr尝试实现复制构造函数,而不是转换构造函数,即:
//this
GameObject(const GameObject &obj);
//instead of this
GameObject(const GameObject *obj);
tl;dr尝试实现复制构造函数,而不是转换构造函数,即:
//this
GameObject(const GameObject &obj);
//instead of this
GameObject(const GameObject *obj);
不是复制构造函数,您需要:
GameObject::GameObject(const GameObject &ob)
^^^
此外,还需要提供一个执行深度复制的复制分配操作符
请注意,理想的解决方案是使用智能指针作为成员,而不是原始指针。这将基本上为您节省所有深度复制的麻烦
读得好:
不是复制构造函数,您需要:
GameObject::GameObject(const GameObject &ob)
^^^
此外,还需要提供一个执行深度复制的复制分配操作符
请注意,理想的解决方案是使用智能指针作为成员,而不是原始指针。这将基本上为您节省所有深度复制的麻烦
读得好:
我发现您没有Location对象的复制构造函数的实现。我想只要实现方法Location(const Location*loc),问题就会得到解决
我看到您没有Location对象的复制构造函数的实现。我想只要实现方法Location(const Location*loc),问题就会得到解决
首先,正如其他人指出的,您没有实现复制构造函数
GameObject::GameObject(const GameObject *ob)
这是一个函数,它获取指向const游戏对象的指针。复制构造函数应该对要从中创建它的对象进行常量引用:
GameObject::GameObject(const GameObject &ob)
然而,我也看到了另一个问题。如果确实需要深度复制,这意味着您希望位置对象是独立的,并且修改一个对象不应影响另一个对象。鉴于此,我认为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(const Location &loc);
我将把该实现作为练习留给读者。;)
也可以阅读一些你的评论(比如上面的静态评论),这实际上不是静态的,这样我就觉得你可能想在C++中多读一些关于内存管理的内容。谷歌在“C++免费商店”上的排名有所上升。提示不要在不必要的地方使用动态内存。在C++中,不是每个对象都应该用<代码>新< <代码> >
,正如其他人指出的,您没有实现复制构造函数。GameObject::GameObject(const GameObject *ob)
这是一个函数,它获取指向const游戏对象的指针。复制构造函数应该对要从中创建它的对象进行常量引用:
GameObject::GameObject(const GameObject &ob)
然而,我也看到了另一个问题。如果确实需要深度复制,这意味着您希望位置对象是独立的,并且修改一个对象不应影响另一个对象。鉴于此,我认为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(const Location &loc);
我将把该实现作为练习留给读者。;)
也可以阅读一些你的评论(比如上面的静态评论),这实际上不是静态的,这样我就觉得你可能想在C++中多读一些关于内存管理的内容。谷歌在“C++免费商店”上的排名有所上升。提示不要在不必要的地方使用动态内存。在C++中,不是每个对象都应该用<代码> < < />代码> .< /p> 在C++中创建,对象可以在堆上创建,它们的内存地址存储在指针中。对象也可以在堆栈上创建,并可以由引用指示
在定义复制构造函数时,我们需要使用引用而不是指针。原因是在复制构造函数中使用指针会导致堆中有两个指针指向同一对象。因此,你的<代码>“Obj6”/“代码>和<代码>”Obj4“指向内存中相同对象的指针。< P> C++中,对象可以在堆上创建,它们的内存地址存储在指针中。对象也可以在堆栈上创建,并可以由引用指示
在定义复制构造函数时,我们需要使用引用而不是指针。原因是在复制构造函数中使用指针会导致堆中有两个指针指向同一对象。因此,您的
“obj6”
和“obj4”
指针指向内存中的同一对象。事实上,如果他进行深度复制,他不很可能想要一个初始化为相等(复制)的位置,而不是引用同一位置(指针)的另一种方式吗?@Agentlien:是的,他需要复制到一个位置
,该位置类似于他复制的类的位置
对象成员。注:相似与不相同。顺便说一句,我并没有完全理解你的评论。我的意思是,他的使用场景让他看起来像是希望游戏对象总是有一个位置。所以,根本没有理由动态地持有它。他不应该使用智能指针,而应该只有一个位置成员。@Agentlien:Perfect。我碰巧不明白