wuno
wuno

Reputation: 9885

Using Member Variables That Are Private c++

I added all my code.

The exact problem I am facing is when I make the member variables private in the game.h file I get an error in the game.cpp file that says n p h are all private members of game.h. in Xcode.

But when I compile the program from the command line it compiles fine with no errors.

I am trying to understand if I am doing something wrong or is this up to standards the way I am doing this?

This is main.cpp

#include "game.h"


int main() {

   game g("Female", "Magic", true, 21, 5, 120);

    std::cout << "These are the things every game needs to be a game" << '\n';

    std::cout << g << '\n';

    return 0;
}

game.cpp

#include <iostream>

#include "game.h"

std::ostream& operator<<(std::ostream& s, const game& g) {
    return s << &g.n << ' ' << &g.p  << ' ' <<  &g.h;
}

This is my composite class

#include <iostream>

#include "npc.h"
#include "pc.h"
#include "health.h"

class game {
private:
    npc n;
    pc p;
    health h;

public:
    game(const npc& init_n, const pc& init_p, const health& init_h):
    n(init_n),
    p(init_p),
    h(init_h)
    {}


    game(std::string gen, std::string abil, bool use, int lvl, int h, int arm) :
    n(gen, abil),
    p(use, lvl),
    h(h, arm)
    {
    }

 friend std::ostream& operator<<(std::ostream& s, const game& g) {
         g.n.output(s);
         g.p.output(s);
         g.h.output(s);
        return s;
 }

     npc get_n() { return n; }
     pc get_p() { return p; }
     health get_h() { return h; }

     void set_n(npc init_n) { n = init_n; }
     void set_p(pc init_p) { p = init_p ; }
     void set_h(health init_h) { h = init_h; }
};

Here is a class

#include <iostream>

class health {
private:
    int hp;
    int armor;

public:
    health(int init_hp, int init_armor) :
    hp(init_hp),
    armor(init_armor)
    {
    }

public:
    void output(std::ostream& s) const { s << "Characters have this amount of hit points "<< hp << " and an armor rating of " << armor << "\n";  }

    };

Here is a class

class pc {
private:
    bool user;
    int level;

public:
    pc(bool init_user, int init_level) :
    user(init_user),
    level(init_level)
    {
    }

public:
    void output(std::ostream& s) const { s << "A player character has at least "<< user << " user and a level of " << level << '\n';  }

};

Here is a class

#include <iostream>

class npc {
private:
    std::string gender;
    std::string ability;

public:
    npc(std::string init_gender, std::string init_ability) :
    gender(init_gender),
    ability(init_ability)
    {
    }

public:
  void output(std::ostream& s) const { s << "A non player character has a gender of "<< gender << " and an ability of " << ability << '\n';  }

};

Upvotes: 0

Views: 93

Answers (1)

Carlo Wood
Carlo Wood

Reputation: 6821

You made several errors - a typo is the reason for your problem. The function is not allowed to access those members because it is not a friend of the class. The friend is (correctly) std::ostream& operator<<(std::ostream& s, const game& g) while you defined a function std::ostream& operator<<(std::ostream& s, const game g), note the missing ampersand.

Also, your accessors should be const, and return a const reference. Ie,

 npc const& get_n() const { return n; }
 pc const& get_p() const { return p; }
 health const& get_h() const { return h; }

Your manipulators change the wrong variables! You change the ones passed to the function instead of the members of that class.... However, it is highly questionable that you add direct manipulators for the three private members. You must view your class as some abstract object and define operators that work on that object. If you just give direct access to all it's members than there is little left of the object orientation idea behind using a class with private members (this would still be ten times better than making them public though!)

Finally, just a coding style hint. It is common practice to use CamelCase names for custom classes (ie, class Game), and you're better of adding a prefix to your private members to distinguish them from function parameters. Often people use the prefix m_. You really should use complete english words too (not abbreviations, let alone single characters).

This would turn your code into, say...

class Game {
  private:
    Npc m_npc;
    Pc m_pc;
    Health m_health;

  public:
    Game(Npc const& npc, Pc const& pc, Health const& health) :
        m_npc(npc), m_pc(pc), m_health(health) { }

etc.

Upvotes: 3

Related Questions