-2
#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!

Ares
  • 25
  • 2
  • 1
    [How do I ask a good question?](http://stackoverflow.com/help/how-to-ask) – R Sahu Feb 25 '16 at 05:46
  • 1
    There are several things wrong with your code. Your copy constructor is missing copying all of the members. In your 3 argument constructor, you failed to initialize `tool` to NULL. you're missing an assignment operator for `Warrior`, and probably more errors. Why get involved with pointers anyway? Just have `Item tool;` in the `Warrior` class, remove the erroneous copy constructor, make `GiveTool` do a simple `tool = Item(tool, whatever)` (without the `new`) and most of your problems go away. – PaulMcKenzie Feb 25 '16 at 05:46
  • @PaulMcKenzie it's for an assignment. I need to use pointers. Which involves dynamic allocation and deallocation – Ares Feb 25 '16 at 16:40
  • @Ares -- Many people take C++ courses, and their assignments have them use objects, not pointers. So just because it is an assignment doesn't automatically mean "use pointers" for many of us here. – PaulMcKenzie Feb 25 '16 at 17:16

3 Answers3

1

In class Warrior, tool is a pointer - Item *tool. So, use * to get an object.

Next, to be able to print an object of class Item by using stream, you should overload << operator. Another way is to define, say, get_name() method for that class:

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

This function returns a constant reference to the name field, what is more efficient than returning a full copy and protects from possible modification outside of class. As well, the method is constant, that means no values can be modified inside of it. Then, you can write this: cout << tool->get_name()

Djura
  • 13
  • 4
1

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).
Community
  • 1
  • 1
PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • Hey i really appreciate the time you took to correct my errors! I will definitely look back at this to help me with future assignments... Thank you kind sir!!! – Ares Feb 26 '16 at 06:09
0

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

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

Check for nullptr first.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63