Pointer issue? This issue? class issue?

Ares
#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;
}

I'm also have trouble display this function... How do i call it?

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;
}

The problem seems to be here i think... So here's what i want to do.

If tool is NULL meaning the warrior has no tool give him a tool. However if he does have a tool, deallocate the tool variable and give him this tool instead.

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);
  }
}

Then how would i display that newly allocated tool... would it just be "tool" like how i did here? Because when i run the program it would display the address not the memory.

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();
}

The output should look like this i think:

Stephen Curry is a level 30 NBA Player

His tool is: Bastketball

Stephen Curry's existing tool is being replaced.

Item Basketball is being deallocated.

Stephen Curry is a level 30 NBA Player

His tool is: Football

Thank you in advance! Also ANYTHING will help. I'm very new to this programming world, keep that in mind when reading my code... Once again any help is appreciated Thanks!

PaulMcKenzie

You could have written your program using Item objects instead of pointers to Item, and not have most of the issues you're having not even appear.

Having said this, there are several things wrong with your code:

  1. You did not initialize tool to NULL (better, nullptr) in your 3 argument Warrior constructor.
  2. You did not copy all of your members in the Warrior copy constructor from the passed-in object to this.
  3. You are missing a destructor for Warrior.
  4. You are missing the assignment operator (Warrior::operator=) for Warrior.

For the first issue:

Warrior::Warrior(string n, int l, string p) : 
                 name(n), level(l), profession(p), tool(nullptr) {}

Note the usage of the member initialization list.

Second issue:

Warrior::Warrior(const Warrior& otherObj) :  
name(otherObj.name), level(otherObj.level), profession(otherObj.profession), tool(nullptr)
{
  if (otherObj.tool)
     tool = new Item(*(otherObj.tool));
}

Note that all members are initialized using the passed-in object's members.

Third issue:

Warrior::~Warror() { delete tool; }

Fourth issue: The assignment operator, using the copy / swap idiom should look something like this:

#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;
} 

To sum this all up:

  1. When you have a class that contains pointers to dynamically allocated memory, and you are making copies of this object in your program, you should respect the rule of 3. You failed to do this by having a missing assignment operator and destructor in Warrior. Failure to adhere to this rule will cause undefined behavior in your program.
  2. When writing a user-defined copy constructor, you should copy all of the members, not just one or two of the members. Having partial copies of an object is one of the toughest bugs to diagnose. The one major exception to the rule of copying all members is if your object is being reference counted.
  3. When constructing an object, you should initialize your pointer members to some state (usually nullptr).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related