We can access private variables of another class when we define copy or move constructors. Does C++ make them friend to each other automatically?
For example:
my_str::my_str(my_str&& m)
{
size_ = m.size_; //accessing private variable another my_str class
buff_ = m.buff_; //accessing private variable another my_str class
m.buff_ = nullptr;
m.size_ = 0;
}
It is not considered friend, but yes, any member function of class my_str can access private members of all instances of type my_str, not just the this instance:
class my_str {
void foo(my_str& other) {
// can access private members of both this-> and other.
}
static void bar(my_str& other) {
// can access private members of other.
}
};
The general idea behind it is to allow 2 or more objects of the same type to interact without having to expose their private members.
Member functions of the class itself always have access to the private members, no matter whether the member function is defined in-class or out-of-class and no matter whether it is a special member function such as a copy/move constructor.
Therefore they are not friend of the class, because that doesn't make any sense. They are already part of the class. Still, they have access to all private members, not because they are friends, but because they are part of the class.
If it wasn't possible to initialized members in a constructor (because they are inaccessible), then the whole concept of member accessibility would be pointless. (How would you initialize the member?)
Also, accessibility is not in any way a matter of the object on which a member is accessed. Accessibility is a matter only of where in the code a name (the name of the member) is used. If a function can access the member of one instance of a class, then it can also access the member of another instance of the same class.
Related
If I will define a private static field in class. Given that it's a private field, can't I initialize it outside the class?
class X{
static int private_static_field;
public:
static void setPrivateStaticField(int val);
};
void X::setPrivateStaticField(int val) {
private_static_field = val;
}
int X::private_static_field(0); // something like that it's ok? if yes, I must write this line? why? can I write it in main?
It's look that it's ok (according to the compiler), but if so, I don't understand the concept of private - How it's ok if it's outside the class?
In addition, given the class above, and the next code:
int main() {
X x1();
x1.setPrivateStaticField(3);
return 0;
}
What is the meaning of x1.setPrivateStaticField(3); , after all, this function is static and hence it's not related to some object.
Hence, I don't understand how it's ok to call setPrivateStaticField with object (x1) ?
(I thought that just X::setPrivateStaticField(3); will be ok and that x1.setPrivateStaticField(3); will be error)
I don't understand the concept of private - How it's ok if it's outside the class?
There is no contradiction here. Prior to C++ 17 static member variables required a definition that is placed separately from the class declaration.
Despite the fact that the text of the definition is placed outside the class, the member variable remains part of the class where it is declared, and retains its accessibility according to its declaration inside the class. This includes private accessibility.
What is the meaning of x1.setPrivateStaticField(3); , after all, this function is static and hence it's not related to some object.
Although C++ compiler lets you call static member functions on the object, it is cleaner to call them using scope resolution operator :: and the class name:
X::setPrivateStaticField(3);
Allowing or disallowing class method calls on an instance is up to the designers of the language. C++ designers decided to allow it; designers of other programming languages disallow it, or require compilers to issue a warning.
Within a class definition static data members are declared but not defined. So they even can have an incomplete type.
So this record
int X::private_static_field(0);
is a definition of the static data member declared in the class definition like
class X{
static int private_static_field;
// ...
This record
x1.setPrivateStaticField(3);
means an access to a class member. Static members are also class members. Using this access method the compiler will know to search the name setPrivateStaticField in the class definition because the name x1 defines an object of the class X.
Another way to access a static member is to use the following record
X::setPrivateStaticField
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**/
}
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.
Suppose I have the following class:
class Test
{
int num;
public:
Test(int x):num(x){}
Test(const Test &rhs):num(rhs.num+1){}
};
int main()
{
Test test(10);
Test copy = test;
}
The num in the copy should be 11, and my question is about inside the copy constructor, why can we access the private member num of test using num to initialize the num in the copy? What is confusing me is that if you type cout<<test.num<<endl, of course it's wrong because you are trying to access the private num, but if you pass the test by reference to the copy constructor, it works, can anybody tell me what is going on here?
Private members are private to the class itself, not the instances of the class.
Access limitations are per-class, not per-object.
"private" means -- can only be accessed from within the same class.
"protected" means -- can be accessed from within the same class, and can also be accessed from within derived-classes (in derived classes, protected non-static members can only be accessed through variables with derived class type).
"public" means -- can be accessed by anything.
The point of access limitations is to limit the region of code that has to be inspected in order to understand where the values are used, rather than to stop code from using the values.
private doesn't mean private to the object instance. It means private to that class. An instance of a class T can access private members of other instances T. Similarly, a static method in a class T can access private members of instances of T.
If private restricted access to only the individual instance, it would make objects non-copyable, since as you pointed out, the copy constructor would not be able to read data from the original instance.
I can declare private static member variables in a class, but what does it mean?
What is the difference private static and public static member variables?
It means these variables cannot be accessed anywhere except within the class itself.
public members can be accessed from outside the class.
protected members can be accessed in the class and its derived classes &
private members can be only accessed within the class.
Note that the member being static or not the same Access Specification rules apply to it.
static implies the storage specification and that the some member will be shared across all the instances of the class it does not change where the member can be accessed.
Good Read:
What are access specifiers? Should I inherit with private, protected or public?
A private variable means it can only be accessed within the scope of the class it is declared in, that is, any functions declared outside the class cannot access (read or write) the private variable.
Declaring a variable as static means that it will hold the same value across all instances of that class.
You may want to do that if you need to hide information (private) and to have a class variable instead of an object variable (static)
Imagine you have a class A with a static int member called a
class A {
public:
static int a;
};
and lets say from your main function you access this as you do using
int new_variable = A::a;
This works fine because your access specifier is public.
Now change it from public to private (or protected) and your code won't compile because private members can only be accessed by the class itself.