【问题标题】:Pointer issue? This issue? class issue?指针问题?这个问题?班级问题?
【发布时间】:2016-06-07 17:49:17
【问题描述】:
#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);
  }
}

那么我将如何显示新分配的工具... 它会像我在这里所做的那样只是“工具”吗? 因为当我运行程序时,它会显示地址而不是内存。

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 球员

他的工具是:足球

提前感谢您!任何事情都会有所帮助。我对这个编程很陌生 世界,在阅读我的代码时请记住这一点...... 再次感谢任何帮助谢谢!

【问题讨论】:

  • 您的代码有几个问题。您的复制构造函数缺少复制所有成员。在您的 3 参数构造函数中,您未能将 tool 初始化为 NULL。您缺少Warrior 的赋值运算符,并且可能还有更多错误。为什么要参与指针?只需在Warrior 类中添加Item tool;,删除错误的复制构造函数,让GiveTool 执行一个简单的tool = Item(tool, whatever)(没有new),你的大部分问题都会消失。
  • @PaulMcKenzie 这是为了分配任务。我需要使用指针。其中涉及动态分配和释放
  • @Ares -- 许多人参加 C++ 课程,他们的作业要求他们使用对象,而不是指针。因此,对于我们这里的许多人来说,仅仅因为它是一个赋值并不意味着“使用指针”。

标签: c++ class pointers this


【解决方案1】:

您可以使用Item 对象而不是指向Item 的指针来编写程序,并且您甚至没有出现大多数问题。

话虽如此,您的代码有几个问题:

  1. 您没有在您的 3 参数 Warrior 构造函数中将 tool 初始化为 NULL(更好的是 nullptr)。
  2. 您没有将 Warrior 复制构造函数中的所有成员从传入的对象复制到 this
  3. 您缺少Warrior 的析构函数。
  4. 您缺少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;
} 

总结一下:

  1. 当您有一个包含指向动态分配内存的指针的类,并且您在程序中制作该对象的副本时,您应该尊重rule of 3。由于Warrior 中缺少赋值运算符和析构函数,您未能做到这一点。不遵守此规则将导致您的程序出现未定义的行为。
  2. 在编写用户定义的复制构造函数时,您应该复制所有成员,而不仅仅是一两个成员。拥有对象的部分副本是最难诊断的错误之一。复制所有成员规则的一个主要例外是,如果您的对象正在被引用计数。
  3. 构造对象时,应将指针成员初始化为某种状态(通常为nullptr)。

【讨论】:

  • 嘿,我非常感谢您花时间纠正我的错误!我一定会回头看看这个,以帮助我完成未来的任务......谢谢你好心的先生!!!
【解决方案2】:

class Warrior 中,工具是一个指针 - Item *tool。所以,使用* 来获取一个对象。

接下来,为了能够使用流打印Item 类的对象,您应该重载&lt;&lt; 运算符。另一种方法是为该类定义 get_name() 方法:

const std::string & Item::get_name() const
{
  return name;
}

此函数返回对name 字段的常量引用,这比返回完整副本更有效,并且可以防止在类外进行可能的修改。同样,该方法是恒定的,这意味着不能在其中修改任何值。 然后,你可以这样写: cout &lt;&lt; tool-&gt;get_name()

【讨论】:

    【解决方案3】:

    我也无法显示此功能...我该如何调用它?

    tool->Describe();  // From the Warrior class
    

    首先检查 nullptr。

    【讨论】:

      猜你喜欢
      • 2022-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多