Error c2248 cannot access private member declared in class

C++ Documentation. Contribute to MicrosoftDocs/cpp-docs development by creating an account on GitHub.
description title ms.date f1_keywords helpviewer_keywords ms.assetid

Learn more about: Compiler Error C2248

Compiler Error C2248

09/27/2022

C2248

C2248

7a3ba0e8-d3b9-4bb9-95db-81ef17e31d23

Compiler Error C2248

member‘: can’t access ‘access_level‘ member declared in class ‘class

Remarks

Members of a derived class can’t access private members of a base class. You can’t access private or protected members of class instances.

Example

The following sample generates C2248 when private or protected members of a class are accessed from outside the class. To fix this issue, don’t access these members directly outside the class. Use public member data and member functions to interact with the class.

// C2248_access.cpp
// compile with: cl /EHsc /W4 C2248_access.cpp
#include <stdio.h>

class X {
public:
    int  m_publicMember;
    void setPrivateMember( int i ) {
        m_privateMember = i;
        printf_s("n%d", m_privateMember);
    }
protected:
    int  m_protectedMember;

private:
    int  m_privateMember;
} x;

int main() {
    x.m_publicMember = 4;
    printf_s("n%d", x.m_publicMember);
    x.m_protectedMember = 2; // C2248 m_protectedMember is protected
    x.m_privateMember = 3;   // C2248  m_privMemb is private
    x.setPrivateMember(0);   // OK uses public access function
}

Another conformance issue that exposes C2248 is the use of template friends and specialization. To fix this issue, declare friend function templates by using either an empty template parameter list <> or specific template parameters.

// C2248_template.cpp
// compile with: cl /EHsc /W4 C2248_template.cpp
template<class T>
void f(T t) {
    t.i;   // C2248
}

struct S {
private:
    int i;

public:
    S() {}
    friend void f(S);   // refer to the non-template function void f(S)
    // To fix, comment out the previous line and
    // uncomment the following line.
    // friend void f<S>(S);
};

int main() {
    S s;
    f<S>(s);
}

Here’s another conformance issue that exposes C2248: You attempt to declare a friend of a class, but the class isn’t visible to the friend declaration in the scope of the class. To fix this issue, grant friendship to the enclosing class.

// C2248_enclose.cpp
// compile with: cl /W4 /c C2248_enclose.cpp
class T {
    class S {
        class E {};
    };
    friend class S::E;   // C2248
};

class A {
    class S {
        class E {};
        friend class A;  // grant friendship to enclosing class
    };
    friend class S::E;   // OK
};

I´m getting this error in a c++ application:

error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' :
              cannot access private member declared in class '

I have seen similar questions in stackoverflow, but I couldn’t figure out what’s wrong with my code. Can someone help me?

    //header file
class batchformat {
    public:
        batchformat();
        ~batchformat();
        std::vector<long> cases;        
        void readBatchformat();
    private:
        string readLinee(ifstream batchFile);
        void clear();
};


    //cpp file
void batchformat::readBatchformat() 
{
    ifstream batchFile; 
    //CODE HERE
    line = batchformat::readLinee(batchFile);

}


string batchformat::readLinee(ifstream batchFile)
{
    string thisLine;
    //CODE HERE
    return thisLine;
}

Filip Roséen - refp's user avatar

asked Jul 15, 2013 at 13:19

guilhermecgs's user avatar

guilhermecgsguilhermecgs

2,86910 gold badges36 silver badges65 bronze badges

2

The problem is:

string readLinee(ifstream batchFile);

This tries to pass a copy of the stream by value; but streams are not copyable. You want to pass by reference instead:

string readLinee(ifstream & batchFile);
//                        ^

answered Jul 15, 2013 at 13:21

Mike Seymour's user avatar

Mike SeymourMike Seymour

247k28 gold badges442 silver badges638 bronze badges

string batchformat::readLinee(ifstream batchFile)

is trying to copy the ifstream
Take it by ref instead

string batchformat::readLinee(ifstream& batchFile)

answered Jul 15, 2013 at 13:21

doctorlove's user avatar

Your error is that you can not pass the ifstream by value :

string readLinee(ifstream batchFile);

Pass it by ref instead :

string readLinee(ifstream& batchFile);

And I would suggest you to change a lign in the readBatchformat method :

void batchformat::readBatchformat() 
{
    ifstream batchFile; 
    //CODE HERE
    line = this->readLinee(batchFile);
    //      ^^^^^^
}

I think it is more readable.

answered Jul 15, 2013 at 13:21

Pierre Fourgeaud's user avatar

Pierre FourgeaudPierre Fourgeaud

14.2k1 gold badge37 silver badges61 bronze badges

3

  • Remove From My Forums
  • Question

  • Hi,

    When I converted VC6 code to Visual Studio 2010 I got error message:

    error C2248: ‘ABC_Hardware::HardwareMgr::Close’ : cannot access private member declared in class ‘ABC_Hardware::HardwareMgr’ 

    How to fix this?

    Thanks in advance.



    MFC coder

Answers

  •     class HardwareMgr
        {
            static HARDWARE_API int Open(HdwrCookie** pCookie);
            static HARDWARE_API void Close(HdwrCookie* pCookie);
    };

    These methods should be public

     
    class HardwareMgr
    {
    public:
      static HARDWARE_API int Open(HdwrCookie** pCookie);
      static HARDWARE_API void Close(HdwrCookie* pCookie);
    };


    David Wilkinson | Visual C++ MVP

    • Marked as answer by

      Thursday, April 26, 2012 9:41 AM

  • The error was fixed.

    Thanks.


    MFC coder

    • Marked as answer by
      MFC coder
      Thursday, April 26, 2012 7:01 PM

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

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

Hello, if I understand correctly, you are trying to create a dynamic number of label controls.
I currently do not have the source to the CStaticEx class but I can help you through.

First, put an array class in your header file, I recommend CPtrArray or CPtrList.

CPtrArray   m_StaticArray;

Then you will have to add a new and a call to Create() before adding your CStaticEx(s).

int nXaxis,nYaxis;
nXaxis = 0;
nYaxis = 0;

for(int i=0; i < nNumOfCamAttch; i++){
    CRect rect(nXaxis + X_PADDING, nYaxis + Y_PADDING , nXaxis + WIDTH + X_PADDING  , HEIGHT + Y_PADDING);
    nXaxis = X_PADDING + WIDTH + nXaxis ;

    CStaticEx* pStaticCtrl = new CStaticEx;
    pStaticCtrl->Create(_T("Text"), WS_CHILD|WS_VISIBLE, rect, this, nID);

    m_StaticArray.Add(pStaticCtrl);
}

Then, remember to clean it up. In your OnDestroy() handler:

while(m_StaticArray.GetSize() > 0)
{
    CStaticEx* pCtrl = (CStaticEx*)m_StaticArray.GetAt(0);
    m_StaticArray.RemoveAt(0);
    pCtrl->DestroyWindow();
    delete pCtrl;
}

I hope this helps, if I got your goal wrong please let me know and I will help.

Понравилась статья? Поделить с друзьями:
  • Error c2220 следующее предупреждение рассматривается как ошибка
  • Error c2220 warning treated as error no object file generated
  • Error c2220 the following warning is treated as an error
  • Error c2169 intrinsic function cannot be defined
  • Error c2146 синтаксическая ошибка отсутствие перед идентификатором