Nathaniel G.M.
Nathaniel G.M.

Reputation: 433

How to access out-of-scope class?

First of all, I would like to apologize if I used incorrect terminology in the question. I do not have any sort of formal training in programming. It was the best I could do to convey the problem.

My question is this:

In the following code structure, how can the Inventory class have complete access to Items vector inside the Player class WITHOUT making the vector static?

-- main.cpp

#include <iostream>
#include <vector>

#include "World.hpp"
#include "Interface.hpp"

int main()
{
    World objWorld;
    Interface objInterface;
    return 0;
}

-- World.hpp

#pragma once
#include "Player.hpp"

class World
{
public:
    Player objPlayer;
};

-- Player.hpp

#pragma once

class Player
{
public:
    std::vector<int> Items;
};

-- Interface.hpp

#pragma once
#include "Inventory.hpp"

class Interface
{
public:
    Inventory objInventory;
};

-- Inventory.hpp

#pragma once

class Inventory
{
public:
    // Needs to have complete access to Items, be able to see and modify the vector
};

Upvotes: 0

Views: 91

Answers (3)

Walter
Walter

Reputation: 45414

There are several issues which you have to consider.

  1. access rights. From outside a class (i.e. from any code other than the class's member functions etc) only public members are accessible, except for friends, which have full access.
  2. visibility. In order to use a member, you must see its declaration.

Thus, you should

// Inventory.hpp
#pragma once
#include "World.hpp"  // makes class World visible
class Inventory
{
    World& objWorld;  // reference to 'my' world object
public:
    Inventory(World& w) : objWorld(w) {}
    void foo()
    {
        std::sort(objWorld.objPlayer.Items.begin(),
                  objWorld.objPlayer.Items.end());
    }
};

Of course, you must adapt the rest of your code accordingly:

// Interface.hpp

#pragma once
#include "Inventory.hpp"

class Interface
{
    Inventory objInventory;
public:
    Interface(World& w) : objInventory(w) {}
};

and

// main.cpp

#include "Interface.hpp"

int main()
{
    World objWorld;
    Interface objInterface(objWorld);
    return 0;
}

Upvotes: 1

user3458
user3458

Reputation:

This is not a C++ question, this is Object Oriented Programming question.

There are many ways to do this. But all of them involve more than one object working together. Either the Player has to have a reference (pointer) to Inventory, or the Inventory has to have a reference to player - somehow.

Here are some options:

You can pass a pointer in constructor (this is just a quick example, please use shared pointers)

class Inventory
{
private:
   Player *owner;
public:
   Inventory(Player *owner) : owner(owner){}
};

Pass it as method argument

class Inventory
{
public:
   void drawFor(Player *owner);
};

Set a field value.

class Inventory
{
private:
   Player *owner;
public:
   void setOwner(Player *owner) {this->owner = owner;}
};

As a side note, are you sure that Player has vector of items? I would venture that Player may OWN an Inventory. Inventory is more than just a vector of items. It has (potentially complex) limitations on number of items, it can maintain weight of items that affects player's movement, it can be expanded by adding containers. All of it can be useful to Player or NPC. You just have to come up with a good interface for Inventory

Upvotes: 2

eerorika
eerorika

Reputation: 238301

Class members can be accessed using the member access operator . (period character). The left hand side is (an expression that yields) an instance of the class, and the right hand side is the name of the member.

Let p be an instance of Player. The expression p.Items will yield the vector of that instance. The class has to be defined, before its members can be accessed.

Upvotes: 0

Related Questions