Note that class x and y are two separate entities and you can not see their private data members from outside of their bodies.
It is known that from int main() I can not see the private member of class x or y.
My question in the following code in line 22:
Why class x can see the private members of class y ? (note here I am sending class y as reference not as a copy) isn't the referenced class y should be protected from strangers like class x ?
Note that the function getForeignNumber(const Player &r) inside class x is not a friend to class y!
#include<iostream>
class Account{
private:
int number{ } ;
public:
Account(int numberValue)
:number{numberValue}
{
std::cout<<"constructor is called"<<std::endl;
}
int getLocalNumber()
{
return this->number;
}
int getForeignNumber(const Account &r)
{
return r.number; // line 22
}
};
int main()
{
Account x{1};
Account y{2};
std::cout<<"get local number="<<x.getLocalNumber()<<std::endl;
std::cout<<"get foreign number x ="<<x.getForeignNumber(x)<<std::endl;
std::cout<<"get foreign number y="<<y.getForeignNumber(y)<<std::endl;
std::cout<<"Hello world"<<std::endl;
return 0;
}
First of all, you are confusing instances of a class with the class. x and y are two instances of the same class Account.
Your analogy isnt sound. Two instances of the same class aren't "strangers". They can access all the internals of each other. Thats how access works.
From cppreference:
All members of a class (bodies of member functions, initializers of member objects, and the entire nested class definitions) have access to all names the class can access. A local class within a member function has access to all names the member function can access.
In other words, access is per class not per instance. If x would not be able to access ys private members it would be impossible for example to write a copy constructor (without getter methods, which would be silly).
PS: By the way, "see" is the wrong word. There are certain circumstances where you can "see" that there is a private member from outside of the class, you just cannot access it. One such situation is when the name of a private method shadows that of a publicly inherited method https://godbolt.org/z/Kzf5KWv4W. Hence, even colloquially "see" is the wrong word for access.
The function getForeignNumber() can see private members of class Account because getForeignNumber() is a member of class Account.
private members are hidden from entities that are outside the class, not from other instances (objects) of the same class.
Related
Now I have here a code snippet that I am trying to understand. I thought that only friend functions could access private member variables, so why is the method 'grad' able to access 'a' here to get its size?
#include <vector>
using namespace std;
class Polynom{
private:
vector<double> a;
public:
Polynom(const vector<double>& v): a(v) {}
int grad() { return a.size()-1; }
};
int main()
{
return 0;
}
Ask yourself, if private member access disqualified the rest of the class from access, what would be the point of a private field? You declare a potentially complex object, and then literally can do nothing with it? You have a private region that can interact with itself, but which cannot have any effect on any public facing functionality? You use the private structures as middlemen to write to public fields that you then use? None of these scenarios makes that much sense. Access modifiers protect the class from external influences, but the OOP model assumes the programmer will take care of themselves within the class.
It is noteworthy that there is one condition in which private members can not be accessed: Inheritance. The base class private variables are there in a derived class, but cannot be referenced directly. To be clear,these are the base class' private variables. The child class has its own private scope that it can declare within and access normally.
My code:-
#include<iostream>
using namespace std;
class a{
private:
int x;
public:
a(int data)
{
x=data;
}
friend void printPrivateMember(a);
};
void printPrivateMember(a obj)
{
cout<<obj.x; //I can access private data member by an object inside this function.
}
int main()
{
a obj1(5);
printPrivateMember(obj1);
cout<<obj1.x; //this gives error
return 0;
}
I wanted to know as to how can I access a PRIVATE data type by an object in the friend function but cannot do so in main.
When I read about access specifier . It was specified that private can be accessed by only member functions (I don't have a problem with the friend function) and not by the object of that class. I wanted to know as to what difference is there because of which I can access private member by an object in one case and cannot do so in another. The same is applicable for copy constructor.
That's exactly what friend functions do: any friend function of a class can access it's private members. Since your printPrivateMember is declared as a friend of a, it can access it's private x member. Since main is not a friend function, it can't.
Forestalling a question about declaring main as friend, this question covers it.
Because friends could do that.
$11/1 Member access control [class.access]
(emphasis mine)
1 A member of a class can be
(1.1) โ private; that is, its name can be
used only by members and friends of the class in which it is
declared.
(1.2) โ protected; that is, its name can be used only by
members and friends of the class in which it is declared, by classes
derived from that class, and by their friends (see 11.4).
(1.3) โ
public; that is, its name can be used anywhere without access
restriction.
As you correctly observed, only member functions (including constructors and destructors) and friend functions and classes may access you're privates. That's the purpose of friends: they provide an exception (not std::exception) to the encapsulation mechanism.
Now you may think about whether this breaks encapsulation or actually stabilizes it.
if you want to access private member, you'd better use a public function like:
class a {
private:
int m;
public:
int getM() {
return m;
}
};
Your use of the phrase not by the object of that class makes me think that you are unclear on the access rules. The access rules don't apply to the objects but who can access member variables and member functions of the objects.
A member variable of a class can be accessed in a function -- which can be a member function of the class, a member function of another class, or a global function.
It can also be accessed in the global space, e.g. to initialize a global variable.
A friend declaration in a class changes the default access rules that are in place by use of private, protected, and public access specifiers.
A function declared a friend of a class can access all the members of all instances of the class.
The answer by songyuanyao cites the section of the standard that provides more details on the subject.
This function should be public, so that you can access it through main().
void print(){
/**print or return your private variable here**/
}
I saw something like the following in a IKM test, the code is in a single file:
class A{
public:
int a;
A();
protected:
int x;
private:
int y;
};
void ARandomFunction(){
//Implementation
}
which variables of class A can ARandomFunction() access? Generally speaking what can be accessed if the decalarations are all in the same file?
Those variables will be per-instance (non-static member variables), so you first need to create an object to access them. Only public members can be accessed from a free-standing function unless the function is declared friend of that class in which case all members can be accessed.
That said it doesn't matter if they are in the same file or not. Once the class definition is visible where the function is implemented the members can be accessed.
Being in the same file changes nothing, your function can only access a as it is public and your function is not a member of A (for the private members) nor a sub class of it (for the protected members).
To my knowledge, using your above example ARandomFUnction can access the public variables and functions regardless of inheritance. THe protected variables can only be accessed if ARandomFunction is contained in a class that inherits from or is a member of class A. Private variables and methods can only be accessed from the same class.
This question already has answers here:
can you access private member variables across class instances?
(2 answers)
Closed 9 years ago.
I have this project in our signals class which uses C++. I was tinkering with our instructors code when I saw this:
ListData::ListData(const ListData& newlist)
: Data(), nbNodes(newlist.nbNodes) {}
This is a "copy constructor" as he says, and should be roughly equivalent to the following:
ListData::ListData(const ListData& newlist){
Data = "";
//copy nbNodes of newList to current instance
nbNodes = newlist.nbNodes;
}
But what bothers me is that nbNodes is a private member. How could this constructor access the nbNodes of the passed newList if it's private?
An interesting thing about private members is that two objects of the same type can access each others private members freely. You can think of it as a class is always friends with itself. Since this is the constructor for ListData and newlist is also a ListData, you can access its privates just fine.
Here's an example of this:
#include <iostream>
class foo
{
public:
foo() { }
foo(std::string secret) : secret(secret) { }
void steal_secret(const foo& other) { secret = other.secret; }
std::string get_secret() { return secret; }
private:
std::string secret;
};
int main() {
foo f1("I'm actually a bar");
foo f2;
f2.steal_secret(f1);
std::cout << f2.get_secret() << std::endl;
return 0;
}
f2 happily and easily steals the secret from f1, despite it being private.
The reason for this being allowed is simply because private doesn't mean private to an object - it means private to a class. This eases the implementation of functions such as copy constructors that require doing some work to the internals of two objects of the same class.
The rule comes from the definition of private (ยง11/1):
A member of a class can be
private; that is, its name can be used only by members and friends of the class in which it is declared.
[...]
Note that it is defined in terms of classes and not objects.
The private keyword has class semantics not object semantics. So private members of an object of a class are accessible to other objects of the same class.
nbNodes is private to the ListData class, not to a particular instance of that class. So, inside the code of the class, you can see the private data of other instances of that class.
If it weren't so, every class would have to export "getters" for every single data member in order to perform copy construction and copy assignment.
A copy constructor is just like any other method: as you can access private members of a class from a method of that class, you can do the same with your copy constructor (else, how could you copy the state of an instance to the class to another one?).
Members with private visibility are members that can only be accessed within member functions of the same class they are members of, without restrictions on objects.
If function f() is a member function of class C, it can access the private members of any instance of C, not just those pointed by the implicit this pointer (which, of course, makes this valid for static functions as well, which do not receive a this pointer at all).
From C++ Standard, Chapter 11: Member Access Control:
private; that is, its name can be used only by members and friends of
the class in which it is declared.
That means a private member could be accessed by any members of that class
Here ListData::ListData(const ListData& newlist) is a copy constructor of ListData, which is a member function thus could access class ListData's private member.
I'm having trouble implementing a nested class who's constructor is initialized with some of the enclosing class' private data members.
Example:
Header File:
class Enclosing {
//...Public members
//...Private members
int x, int y
class Inner; // Declaration for nested class
};
Impl. File:
// Stuff...
class Enclosing::Inner {
explicit Inner() : foo(x), bar(y) // foo and bar are data members of Inner
//...
};
I get an invalid use of non-static data member error. Is there something I'm missing when it comes to nested class access to its enclosing class' members?
Member x and y are non-static data member of Enclosing, which means that they only exist within a concrete object of Enclosing class. Without a concrete object, neither x nor y exist. Meanwhile, you are trying to refer to x and y without an object. That can't be done, which is what the compiler is trying to tell you.
If you want to initialize members Inner::foo and Inner::bar from x and y, you have to pass a concrete object of Enclosing type into the Inners constructor. For example
class Enclosing::Inner {
explicit Inner(const Enclosing& e) : foo(e.x), bar(e.y)
{}
//...
};
Extra note: in the original C++98 the inner class has no special privileges is accessing the outer class. With C++98 compiler you'd either have to give the inner class the necessary privileges (friendship) or expose the members x and y as public. However, this situation was classified as a defect in C++98, and it was decided that inner classes should have full access to outer class members (even private ones). So, whether you have to do anything extra with regard to access privileges depends on your compiler.
The problem with your code is not visibility, as pointed out by AndreyT, but that an instance of the Inner class is not bound to a concrete instance of the Enclosing class. The In other words when constructing an Inner the compiler has no way of know which object to take the x and y values from.
You will have to explicitly provide an instance of the Enclosing class to the constructor of the Inner class as so:
class Enclosing
{
private:
int x;
int y;
class Inner
{
private:
int foo;
int bar;
public:
explicit Inner(const Enclosing& e)
: foo(e.x), bar(e.y)
{ }
};
};
nested class can't access privet data member of enclosing class.compiler show a error if we try to access privet member of enclosing class, it can only access the public data member of enclosing class.....