Cannot access private member declared in one class BUT I can in another class

Pages: 12
So I have an ImageManager class, Board class, and Box class. In Board.h I can declare ImageManager imgr; and in Board's constructor I can use imgr and its functions and such. However, in Box.h when I try and declare ImageManager imgr; I get the error "cannot access member declared in class ImageManager". Both declarations are under private, and exactly the same, but one doesn't work. Can anybody help? Also, is there a way to only have one instance of ImageManager?
You have not provided enough information for us to know what the problem is - please provide a minimal example that has the same error, or at the very least paste your code.

As for only having one ImageManager, you can have Board and Box take a reference to an ImageManager in their constructors and then you can construct them both from the same ImageManager. Don't use a singleton though; as a community we've agreed it's more of an anti-pattern.
Last edited on
@LB
Board.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#include "stdafx.h"
#include <vector>
#include "Box.h"
#include "SFML/Graphics.hpp"
#include "ImageManager.h"

class Board{
public:
	Board();
	~Board();

	std::vector<Box> &GetBoxes();

	sf::Sprite GetGameBoard();
private:
	sf::Sprite gameBoard;

	std::vector<Box> boxes;

	ImageManager imgr;
};


and Board's constructor:
1
2
3
4
5
6
7
Board::Board(){
	imgr.AddResourceDirectory("images/");
	//error checking, images/ is indeed in the vector
	//std::cout << imgr.GetResourceDirectory()[0];

	gameBoard.setTexture(imgr.GetImage("t3board.png"));
}

This works. Now Box.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#pragma once
#include "stdafx.h"
#include "SFML/Graphics.hpp"
#include <vector>
#include "ImageManager.h"

class Box{
public:
	Box();
	~Box();

	void SetDrawn(bool drawn);
	bool GetDrawn();

	void SetShape(char shape);
	sf::Sprite GetShape();

	std::string GetName();
private:
	sf::Sprite shape;
	bool drawn;

	std::string name;

	ImageManager imgr;
};


and Box's constructor:
1
2
3
4
5
6
7
Box::Box(){
	static int namei = 0;
	namei++;
	name = "box" + std::to_string(namei);

	imgr.AddResourceDirectory("images/");
}


I get a compiler error: Error 3 error C2248: 'ImageManager::ImageManager' : cannot access private member declared in class 'ImageManager' Box.h

I don't know why it works for Board.h but not for Box.h
I'll bet you anything it's trying to implicitly access the copy constructor of ImageManager when you try to copy a Box into the vector. Using a reference would definitely solve the problem.
Alright thanks, I think I'll try using just one ImageManager with references like you said. But where would the one instance of ImageManager be? In my game engine class? In the ImageManager class?
I assume you create a single instance of some class in your main function, right? Put the ImageManager instance in that class.
@LB
1
2
3
4
5
6
7
8
9
#include "stdafx.h"
#include "Engine.h"

int _tmain(int argc, _TCHAR* argv[])
{
	Engine e;
	e.Go();
	return 0;
}


That's all my main function does, just call the game loop. What would I need to change?
LB wrote:
I assume you create a single instance of some class in your main function, right? Put the ImageManager instance in that class.
Having reread that thoroughly, what do you think you're doing on line 6? ;p

Put the ImageHandler instance inside your Engine class.
Last edited on
Right, sorry the wording eluded my grasp. Anyways, having done that, how do I access this ImageManager from my other classes? The details of this new problem are in my post here: http://stackoverflow.com/questions/25676303/how-do-i-implement-my-imagemanager?
But essentially, I just want to know how to pass my ImageManager around my whole program from one instance of it.
Have your other classes take references to it via their constructors.

As for your problem,
http://www.cplusplus.com/articles/Gw6AC542/
@LB
1
2
3
4
5
6
7
8
Board::Board(){
	ImageManager &imgr;
	//e.GetManager().AddResourceDirectory("images/");
	//error checking, images/ is indeed in the vector
	//std::cout << imgr.GetResourceDirectory()[0];

	//gameBoard.setTexture(e.GetManager().GetImage("t3board.png"));
}


the semicolon is highlighted, saying "the variable imgr requires an intitializer". I'm sorry i'm not getting this, but it's just not coming to me. In Engine.h, under public, I have declared ImageManager imgr;. What would be the correct way to do this?
The reference to ImageManager needs to be a parameter passed to the constructor and needs to be a class member.
1
2
3
4
5
6
7
8
9
10
struct Example
{
    Example(ImageManager &im)
    : imgr(im)
    {
    }

private:
    ImageManager &imgr;
};
Last edited on
@LB Ok, sorry for not understanding. So I've done exactly that, but I'm still getting an error.
Board.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "Box.h"
#include "SFML/Graphics.hpp"
#include "ImageManager.h"

class ImageManager;

class Board{
public:
	Board(ImageManager &im);
	~Board();

	std::vector<Box> &GetBoxes();

	sf::Sprite GetGameBoard();
private:
	sf::Sprite gameBoard;

	ImageManager &imgr;

	std::vector<Box> boxes;
};


Board.cpp:
1
2
3
4
5
6
7
8
9
10
#include "stdafx.h"
#include "Board.h"

Board::Board(ImageManager &im) : imgr(im){
	im.GetManager().AddResourceDirectory("images/");
	//error checking, images/ is indeed in the vector
	//std::cout << imgr.GetResourceDirectory()[0];

	//gameBoard.setTexture(e.GetManager().GetImage("t3board.png"));
}


"im" is underlined, saying that im has no member GetManager(). This is because the compiler isn't acually seeing im as an ImageManager object, correct? What do I do from here?
This is because the compiler isn't acually seeing im as an ImageManager object, correct

No. It's saying that because it can't find a GetManager() method inside your ImageManager class.

can you post that class header?

edit: From your previous code snippets i'm guessing you want to do this maybe:

 
im.AddResourceDirectory("images/");


In other words you don't need to call GetManager(), as 'im' is your manager object.
I'm just guessing though..
Last edited on
Oh wow, it is definitely a Monday.. GetManager() was what I had in my Engine in my other failed attempt to solve this. Anyways, if I declare the actual imgr, how do I pass that off as a constructor when I create a board object?
I.e. in Engine.h I declare Board board:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#pragma once
#include "stdafx.h"
#include "SFML/Graphics.hpp"
#include "ImageManager.h"
#include "Board.h"
#include <iostream>
#include "Box.h"

class Engine{
public:
	Engine();
	~Engine();

	void Go();
private:
	void ProcessInput();
	void Update();
	void Render();

	void FillVector();

	ImageManager imgr;

	Board board(ImageManager &imgr)


So is &imgr the same imgr that was declared in the previous line? Also, how do I declare a Board object in Engine? Because I used to just have Board board; which makes an object, but with my modified constructor how do I declare this object?
Last edited on
Remove line 24.

Line 22: ImageManager &imgr'

Line 11: Engine(ImageManager &im);
But if imgr is also a reference, when is the acual object made? I did the changes you made, and here's Engine's constructor:
1
2
3
4
5
Engine::Engine(ImageManager &im){
	window.create(sf::VideoMode(260, 260, 32), "Tic Tac Toe");
	FillVector();
	Board board(ImageManager &im);
}


The opening brace is underlined, throwing the error "Engine::Engine(ImageManager &im)" provides no initializer for: reference member "Engine::imgr""

Also, in functions for Engine, board is still undefined:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void Engine::ProcessInput(){
	while(window.pollEvent(event)){
		switch(event.type){
		case sf::Event::Closed:
			window.close();
			break;
		}
		if(sf::Mouse::isButtonPressed(sf::Mouse::Left)){
			sf::Vector2i localMousePos = sf::Mouse::getPosition(window);
			int xc = localMousePos.x;
			int yc = localMousePos.y;
			if(xc <= 80){
				if(yc <= 80){
					board.GetBoxes()[1].SetDrawn(true);
				}


board left of GetBoxes() throws the error that board is undefined. I'm clearly missing something here, but what?
Sorry I hastily misread your code. Ignore my previous post.

What was line 24 trying to do?
Last edited on
In short, line 24 is trying to create a classwide Board object in my Engine class. I could do this before without using a constructor, but now I have to pass an ImageManager parameter through board's constructor, so board becomes not an object
Line 24 looks like a function, not an object. Did you mean this instead?

Board board {imgr};
Pages: 12