Accessing Private Members

How to access private data members outside the class without making friend s?

You can't. That member is private, it's not visible outside the class. That's the whole point of the public/protected/private modifiers.

(You could probably use dirty pointer tricks though, but my guess is that you'd enter undefined behavior territory pretty fast.)

Accessing private members of a class from another class

You have multiple possibilities to access members of other classes.

If a member is private (as in your case) you can either declare other classes as a friend of this class or write getters and setters.

Method 1: Getters and Setters

class A {
private:
int a;
public:
int GetA() { return a; }
void SetA(int newA) { a = newA; }
};

This however will grant access to your private data from every other place in your code. Though you can leave setA away causing only read access to the private a.


Edit:

As @tobi303 has correctly pointed out: Returning a raw pointer via a getter (as it would be in your case) is probably not a good idea. So I would recommend in this case to either return the object the pointer points to or use smart pointers like std::shared_ptr and return them:

class {
private:
int *a;
std::shared_ptr<int> b;
public:
int getA() { return a ? *a : 0; } // only dereference the pointer if it points somewhere
std::shared_ptr<const int> getB() { return b; } // return as std::shared_ptr<const int> to prevent indirect write access to a
};

Method 2: Friend Classes

class B
{};

class A {
private:
int a;
public:
friend class B;
};

In this case only B and A can access the private data of A. You can also grant access to the private data to only a few functions.

However, granting write access to private members often indicates a flaw in your design. Maybe they should be public (see Method 3) or you don't even need write access and just reading them would be completely sufficient for your needs.

Method 3: Public Members

class A {
public:
int a;
};

Similar to Method 1 (with both the getter and the setter) you are now granting read and write access to As member a.

If you really need read and write access to a private member, Method 2 is the way to go. But as I've said: Think about your design once again, do you really need this?

Accessing private member variables of a class from a static method

static myClassPtr create(unsigned int val) {

create() is a static method of myClass, it is a member of this class. As such it it entitled to access all private members and methods of its class. This right extends not only to its own class instance, but any instance of this class.

As per my understanding private members should not be accessible.

... except by members of their class.

Let's create a completely pointless copy constructor for your class, the same copy constructor you would get by default:

myClass(const myClass &o) : m_val{o.m_val} {}

This copy constructor has no issues, whatsoever, of accessing m_val of the passed-in object. Exactly the same thing happens here. m_val is a private member of its class. It doesn't mean that only an instance of the same exact object can access its private members, it means that any instance of the class, or a static class method, can access the private class members.

Accessing private members via reference accessor

The Game class has a cookie member. That is what the Game::getCookie() method should return:

Cookie& Game::getCookie() {
return cookie;
}

Now, inside of the Game constructor, you have direct access to the cookie member, so you don't need to use getCookie() to access it. And the Cookie class has public methods for reading most of the values you are trying to use, but it DOES NOT provide any access to set those member values, or any access to its private initialNumberOfRows member at all.

The things you are trying to do in the Game constructor should be done in the Cookie constructor instead:

Cookie::Cookie() {
initialNumberOfRows = numberOfRows = 4 + rand() % (MAXROWS - 4);

numberOfColumns = numberOfRows;
while (numberOfColumns == numberOfRows) {
numberOfColumns = 4 + rand() % (MAXROWS - 4);
}

cookie = new int[numberofRows];

for (int row = 0; row < numberOfRows; ++row) {
cookie[row] = numberOfColumns;
}
}

Then the Game constructor can log the values as needed:

Game::Game() {
cout << "The cookie has " << cookie.getNumberOfRows() << " rows of "
<< cookie.getNumberOfColumns() << " columns" << endl;
}

Now, that being said, the Cookie class is violating the Rule of Three. It needs to implement a copy constructor and copy assignment operator to ensure the integrity of its int *cookie field:

class Cookie {
public:
Cookie();
Cookie(const Cookie &src);
~Cookie();

Cookie& operator=(const Cookie &rhs);
void swap(Cookie &other);

...

private:
int initialNumberOfRows;
int numberOfRows;
int numberOfColumns
int* cookie;
};

#include <algorithm>

Cookie::Cookie() {
initialNumberOfRows = numberOfRows = 4 + rand() % (MAXROWS - 4);

numberOfColumns = numberOfRows;
while (numberOfColumns == numberOfRows) {
numberOfColumns = 4 + rand() % (MAXROWS - 4);
}

cookie = new int[numberOfRows];
std::fill(cookie, cookie + numberOfRows, numberOfColumns);
}

Cookie::Cookie(const Cookie &src) :
initialNumberOfRows(src.initialNumberOfRows),
numberOfRows(src.numberOfRows),
numberOfColumns(src.numberOfColumns),
cookie(new int[numberOfRows])
{
std::copy(src.cookie, src.cookie + numberOfRows, cookie);
}

Cookie::~Cookie()
{
delete[] cookie;
}

Cookie& Cookie::operator=(const Cookie &rhs)
{
if (this != &rhs)
Cookie(rhs).swap(*this);
return *this;
}

void Cookie::swap(Cookie &other)
{
std::swap(initialNumberOfRows, other.initialNumberOfRows);
std::swap(numberOfRows, other.numberOfRows);
std::swap(numberOfColumns, other.numberOfColumns);
std::swap(cookie, other.cookie);
}

Otherwise, change the int *cookie member to a std::vector instead, and let the compiler and STL handle the hard work of memory management for you:

#include <vector>

class Cookie {
public:
Cookie();

...

private:
int initialNumberOfRows;
int numberOfRows;
int numberOfColumns
std::vector<int> cookie;
};

Cookie::Cookie() {
initialNumberOfRows = numberOfRows = 4 + rand() % (MAXROWS - 4);

numberOfColumns = numberOfRows;
while (numberOfColumns == numberOfRows) {
numberOfColumns = 4 + rand() % (MAXROWS - 4);
}

cookie.resize(numberOfRows);
std::fill(cookie.begin(), cookie.end(), numberOfColumns);
}

Accessing private members of surrounding class

According to the C++ 17 Standard (14.7 Nested classes)

1 A nested class is a member and as such has the same access rights as
any other member.
The members of an enclosing class have no special
access to members of a nested class; the usual access rules (Clause
14) shall be obeyed.

The problem with the provided code is that x is not a static data member of the class A. You need to provide an object of the class A the data member x of which will be accessed within an object of the nested class.

For example

    class A {
public:
class B {
public:
void printX( const A &a ) const { std::cout << a.x << std::endl; }
};
private:
int x;
};

A::B().printX( A() );

how can i access private member += function in c++

The private scope in C++ prevents access from outside. It does not prevent access from objects of the same class. Therefore, the objects instantiated from class Fraction can access each other attribute without any prevention.

When you write

Fraction a, b;
a += b;

It is equivalent as

Fraction a, b;
a.operator+=(b);

Therefore, object a can access attributes of object b easily. However, when you write

Fraction a, b;
Fraction c = a + b;

It is equivalent to

Fraction a, b;
Fraction c = operator+(a, b);

Now, the operator is not the member function of object a, so, it cannot access attributes of object b since it is not accessing on behalf of object a anymore

C++ Accessing a private member in a friend class

A friend class is allowed to access any private member, so you can simply invoke methods and modify properties as you would do if they had been public.

Here the documentation, it says:

The friend declaration appears in a class body and grants a function or another class access to private and protected members of the class where the friend declaration appears.

That said, by looking at your example, I'd rather change the place where to put the friend keyword, for it looks to me that myfunc2 ought not to be public.

It follows an example where I applied the above suggestion and that shows how to deal with private members from a friend class:

#include<unordered_map>

using namespace std;

class firstClass;

class secondClass{
friend class firstClass;

private:
void myfunc2(unordered_map<unsigned,double>& map){
map[1]=0.5;
}
};

class firstClass{
public:
void myfunc1(secondClass* sc){
// here firstClass is accessing a private member
// of secondClass, for it's allowed to do that
// being a friend
sc->myfunc2(STable);
}
private:
unordered_map<unsigned,double> STable;
};

int main(){
firstClass fco;
secondClass sco;
fco.myfunc1(&sco);
return 0;
}


Related Topics



Leave a reply



Submit