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 A
s 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
Cmake Unable to Determine Linker Language with C++
How to Write C++ Getters and Setters
C++11 Equivalent to Boost Shared_Mutex
Understanding Return Value Optimization and Returning Temporaries - C++
How to Iterate Over a Priority_Queue
Why Does the Most Negative Int Value Cause an Error About Ambiguous Function Overloads
C++ Efficiently Calculating a Running Median
Pure Virtual Functions May Not Have an Inline Definition. Why
What's the Difference Between Long Long and Long
How to Use Createthread for Functions Which Are Class Members
Simplest Way to Determine Return Type of Function