指针问题?这个问题? class 问题?
Pointer issue? This issue? class issue?
#include <iostream>
using namespace std;
class Item
{
private:
string name;
int power;
int durability;
public:
Item(string n, int p, int d);
void Describe() const;
~Item();
};
Item::Item(string n, int p, int d)
{
name = n; power = p; durability = d;
}
我也无法显示此功能...如何调用它?
void Item::Describe() const
{
cout << name << " (power=" << power << ", durability=" << durability << ")\n";
}
Item::~Item()
{
cout << "** Item " << name << " is being deallocated." << endl;
}
class Warrior
{
private:
string name;
int level;
string profession;
Item *tool;
public:
Warrior(string n, int l, string p);
Warrior(const Warrior& otherObj);
void GiveTool(string toolName, int toolPower, int toolDurability);
void Describe() const;
};
Warrior::Warrior(string n, int l, string p)
{
name = n;
level = l;
profession = p;
}
Warrior::Warrior(const Warrior& otherObj)
{
if(otherObj.tool != NULL)
this->tool = new Item(*(otherObj.tool));
else
this->tool = NULL;
}
我认为问题似乎出在这里...
所以这就是我想做的。
如果tool为NULL表示战士没有工具给他一个工具。
但是,如果他确实有工具,则释放工具变量
而是给他这个工具。
void Warrior::GiveTool(string toolName, int toolPower, int toolDurability)
{
if(tool == NULL)
this->tool = new Item(toolName,toolPower,toolDurability);
else
{
cout << name << "'s existing tool is being replaced." << endl;
delete tool;
this->tool = new Item(toolName,toolPower,toolDurability);
}
}
那我怎么显示那个新分配的工具...
会像我在这里做的那样 "tool" 吗?
因为当我 运行 程序时它会显示地址而不是内存。
void Warrior::Describe() const
{
cout << name << " is a level " << level << " " << profession << endl;
if(tool != NULL)
{
cout << "His tool is: ";
cout <<tool;
cout << "....";
}
else
{
cout << "No tool\n";
}
}
int main()
{
Warrior a("Stephen Curry", 30, "NBA Player");
a.GiveTool("Basketball", 50, 20);
a.Describe();
a.GiveTool("Football", 10, 20);
a.Describe();
}
我认为输出应该是这样的:
斯蒂芬库里是 30 级 NBA 球员
他的工具是:篮球
Stephen Curry 的现有工具正在被替换。
正在重新分配项目篮球。
斯蒂芬库里是 30 级 NBA 球员
他的工具是:足球
提前致谢!任何事情都会有所帮助。我对这个编程很陌生
世界,在阅读我的代码时请记住这一点......
再次感谢任何帮助谢谢!
I'm also have trouble display this function... How do i call it?
tool->Describe(); // From the Warrior class
首先检查 nullptr。
在class Warrior
中,工具是指针-Item *tool
。所以,使用 *
来获取一个对象。
接下来,为了能够使用流打印 class Item
的对象,您应该重载 <<
运算符。另一种方法是为 class:
定义 get_name()
方法
const std::string & Item::get_name() const
{
return name;
}
此函数 returns 对 name
字段的常量引用,比返回完整副本更有效,并防止可能在 class 之外进行修改。同样,该方法是常量,这意味着不能在其中修改任何值。
然后,你可以这样写:
cout << tool->get_name()
您可以使用 Item
对象而不是指向 Item
的指针来编写您的程序,并且不会遇到您甚至没有出现的大部分问题。
话虽如此,您的代码有几处错误:
- 您没有在第 3 个参数
Warrior
构造函数中将 tool
初始化为 NULL
(更好,nullptr
)。
- 您没有将
Warrior
复制构造函数中的所有成员从传入对象复制到 this.
- 您缺少
Warrior
的析构函数。
- 您缺少
Warrior
的赋值运算符 (Warrior::operator=
)。
第一期:
Warrior::Warrior(string n, int l, string p) :
name(n), level(l), profession(p), tool(nullptr) {}
注意成员初始化列表的用法
第二期:
Warrior::Warrior(const Warrior& otherObj) :
name(otherObj.name), level(otherObj.level), profession(otherObj.profession), tool(nullptr)
{
if (otherObj.tool)
tool = new Item(*(otherObj.tool));
}
请注意,所有成员都是使用传入对象的成员初始化的。
第三期:
Warrior::~Warror() { delete tool; }
第四期:赋值运算符,使用copy / swap idiom应该是这样的:
#include <algorithm>
//...
Warrior& Warrior::operator=(const Warrior& w)
{
Warrior temp(w);
std::swap(temp.tool, tool);
std::swap(temp.name, name);
std::swap(temp.level, level);
std::swap(temp.profession, profession);
return *this;
}
总结一下:
- 当你有一个 class 包含指向动态分配内存的指针,并且你正在程序中复制这个对象时,你应该尊重 rule of 3。由于
Warrior
中缺少赋值运算符和析构函数,您未能做到这一点。不遵守此规则将导致您的程序出现未定义的行为。
- 编写用户定义的拷贝构造函数时,应该拷贝所有个成员,而不是只拷贝一个或两个成员。拥有对象的部分副本是最难诊断的错误之一。复制所有成员规则的一个主要例外是如果您的对象正在被引用计数。
- 构造对象时,应将指针成员初始化为某种状态(通常
nullptr
)。
#include <iostream>
using namespace std;
class Item
{
private:
string name;
int power;
int durability;
public:
Item(string n, int p, int d);
void Describe() const;
~Item();
};
Item::Item(string n, int p, int d)
{
name = n; power = p; durability = d;
}
我也无法显示此功能...如何调用它?
void Item::Describe() const
{
cout << name << " (power=" << power << ", durability=" << durability << ")\n";
}
Item::~Item()
{
cout << "** Item " << name << " is being deallocated." << endl;
}
class Warrior
{
private:
string name;
int level;
string profession;
Item *tool;
public:
Warrior(string n, int l, string p);
Warrior(const Warrior& otherObj);
void GiveTool(string toolName, int toolPower, int toolDurability);
void Describe() const;
};
Warrior::Warrior(string n, int l, string p)
{
name = n;
level = l;
profession = p;
}
Warrior::Warrior(const Warrior& otherObj)
{
if(otherObj.tool != NULL)
this->tool = new Item(*(otherObj.tool));
else
this->tool = NULL;
}
我认为问题似乎出在这里... 所以这就是我想做的。
如果tool为NULL表示战士没有工具给他一个工具。 但是,如果他确实有工具,则释放工具变量 而是给他这个工具。
void Warrior::GiveTool(string toolName, int toolPower, int toolDurability)
{
if(tool == NULL)
this->tool = new Item(toolName,toolPower,toolDurability);
else
{
cout << name << "'s existing tool is being replaced." << endl;
delete tool;
this->tool = new Item(toolName,toolPower,toolDurability);
}
}
那我怎么显示那个新分配的工具... 会像我在这里做的那样 "tool" 吗? 因为当我 运行 程序时它会显示地址而不是内存。
void Warrior::Describe() const
{
cout << name << " is a level " << level << " " << profession << endl;
if(tool != NULL)
{
cout << "His tool is: ";
cout <<tool;
cout << "....";
}
else
{
cout << "No tool\n";
}
}
int main()
{
Warrior a("Stephen Curry", 30, "NBA Player");
a.GiveTool("Basketball", 50, 20);
a.Describe();
a.GiveTool("Football", 10, 20);
a.Describe();
}
我认为输出应该是这样的:
斯蒂芬库里是 30 级 NBA 球员
他的工具是:篮球
Stephen Curry 的现有工具正在被替换。
正在重新分配项目篮球。
斯蒂芬库里是 30 级 NBA 球员
他的工具是:足球
提前致谢!任何事情都会有所帮助。我对这个编程很陌生 世界,在阅读我的代码时请记住这一点...... 再次感谢任何帮助谢谢!
I'm also have trouble display this function... How do i call it?
tool->Describe(); // From the Warrior class
首先检查 nullptr。
在class Warrior
中,工具是指针-Item *tool
。所以,使用 *
来获取一个对象。
接下来,为了能够使用流打印 class Item
的对象,您应该重载 <<
运算符。另一种方法是为 class:
get_name()
方法
const std::string & Item::get_name() const
{
return name;
}
此函数 returns 对 name
字段的常量引用,比返回完整副本更有效,并防止可能在 class 之外进行修改。同样,该方法是常量,这意味着不能在其中修改任何值。
然后,你可以这样写:
cout << tool->get_name()
您可以使用 Item
对象而不是指向 Item
的指针来编写您的程序,并且不会遇到您甚至没有出现的大部分问题。
话虽如此,您的代码有几处错误:
- 您没有在第 3 个参数
Warrior
构造函数中将tool
初始化为NULL
(更好,nullptr
)。 - 您没有将
Warrior
复制构造函数中的所有成员从传入对象复制到 this. - 您缺少
Warrior
的析构函数。 - 您缺少
Warrior
的赋值运算符 (Warrior::operator=
)。
第一期:
Warrior::Warrior(string n, int l, string p) :
name(n), level(l), profession(p), tool(nullptr) {}
注意成员初始化列表的用法
第二期:
Warrior::Warrior(const Warrior& otherObj) :
name(otherObj.name), level(otherObj.level), profession(otherObj.profession), tool(nullptr)
{
if (otherObj.tool)
tool = new Item(*(otherObj.tool));
}
请注意,所有成员都是使用传入对象的成员初始化的。
第三期:
Warrior::~Warror() { delete tool; }
第四期:赋值运算符,使用copy / swap idiom应该是这样的:
#include <algorithm>
//...
Warrior& Warrior::operator=(const Warrior& w)
{
Warrior temp(w);
std::swap(temp.tool, tool);
std::swap(temp.name, name);
std::swap(temp.level, level);
std::swap(temp.profession, profession);
return *this;
}
总结一下:
- 当你有一个 class 包含指向动态分配内存的指针,并且你正在程序中复制这个对象时,你应该尊重 rule of 3。由于
Warrior
中缺少赋值运算符和析构函数,您未能做到这一点。不遵守此规则将导致您的程序出现未定义的行为。 - 编写用户定义的拷贝构造函数时,应该拷贝所有个成员,而不是只拷贝一个或两个成员。拥有对象的部分副本是最难诊断的错误之一。复制所有成员规则的一个主要例外是如果您的对象正在被引用计数。
- 构造对象时,应将指针成员初始化为某种状态(通常
nullptr
)。