What does it actually mean when you declare a variable or a member function as private in a C++ class? Besides the obvious fact that, these are accessible only by the member functions, How are they mapped differently on memory, than their public counterparts?
From standard docs, 9.2.12,
Nonstatic data members of a (non-union) class with the same access control (clause 11) are allocated so that later
members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (11). Implementation alignment requirements might cause two adjacent members not to
be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and
virtual base classes (10.1).
The standards has specs for the order of allocation of memory but there isn't much difference in the memory that is being allocated for a public data member and it's private counterpart..
Imagine that they were only acessible from member functions, then code like this would break:
class Foo {
int x; // this is private
public:
int& X() { return x; } // this is public, but returns a reference to a private variable
};
Foo foo;
foo.X() = 42; // look, I can set the value of a private member without being inside a member function
In short, one of the most common way to define get/setters in C++ would break if there was some sort of magic enforcing that a private variable must only be accessed by member functions. That's obviously no good.
public and private are there to help the programmer structure his code, and nothing more. They offer absolutely no security, and no runtime protection against code accessing a "private" member. Variables are only private in the source code. In the compiled code, there is no difference.
class priva
{
int x=10;
public:
int pub;
};
main()
{
priva a;
int *ptr;
ptr=&a.pub;
--ptr;//4 bite be4 there will be private data
cout<<"Private data having value of 10 is "<<endl;
cout<<*ptr;
}
Other than accesability there is no difference!
public and private are there only until compilation of the code. They don't have anything to do with the runtime or memory management.
Related
I come from C programming where the data in a struct is laid out with the top variable first, then the second, third and so on..
I am now programming in C++ and I am using a class instead. I basically want to achieve the same, but I also want get/set methods and also maybe other methods (I also want to try do it in a C++ style and maye learn something new).
Is there a guarantee e.g. that the public variables will be first in memory then the private variable?
Is there a guarantee e.g. that the public variables will be first in
memory then the private variable?
No, such a guarantee is not made - C++11 standard, [class.mem]/14:
Nonstatic data members of a (non-union) class with the same access
control (Clause 11) are allocated so that later members have higher
addresses within a class object. The order of allocation of non-static
data members with different access control is unspecified (11).
So
struct A
{
int i, j;
std::string str;
private:
float f;
protected:
double d;
};
It is only guaranteed that, for a given object of type A,
i has a smaller address than j and
j has a smaller address than str
Note that the class-keys struct and class have no difference regarding layout whatsoever: Their only difference are access-rights which only exist at compile-time.
It only says the order, but not that the first variable actually start
at the "first address"? Lets assume a class without inheritance.
Yes, but only for standard-layout classes. There is a row of requirements a class must satisfy to be a standard-layout class, one of them being that all members have the same access-control.
Quoting C++14 (the same applies for C++11, but the wording is more indirect), [class.mem]/19:
If a standard-layout class object has any non-static data members, its
address is the same as the address of its first non-static data
member. Otherwise, its address is the same as the address of its first
base classsubobject (if any). [ Note: There might therefore be
unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. — end note ]
[class]/7:
A standard-layout class is a class that:
has no non-static data members of type non-standard-layout class (or array of such types) or reference,
has no virtual functions (10.3) and no virtual base classes (10.1),
has the same access control (Clause 11) for all non-static data members,
has no non-standard-layout base classes,
either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base
classes with non-static data members, and
has no base classes of the same type as the first non-static data member. 110
110) This ensures that two subobjects that have the same class type and that belong to the same most derived object are not
allocated at the same address (5.10).
First thing first: class and struct in C++ are very much the same - the only difference is that all members before the first access specifier in a class are considered private, while in a struct they are public.
Is there a guarantee e.g. that the public variables will be first in memory then the private variable?
There is no such guarantee. When there is no inheritance, the memory will be allocated to class members in the order in which you declare them within the same access group. It is up to the compiler to decide if the public member variables should be placed ahead of the private / protected ones or vice versa. Like C, C++ can add padding in between class members.
Inheritance makes things more complicated, because data members of the base class need to be placed within the derived class as well. On top of that, there is virtual inheritance and multiple inheritance, with complex rules.
I basically want to achieve the same [layout], but I also want get/set methods and also maybe other methods.
If you make all data members of your class private, and add accessor member functions (that's what C++ calls "methods" from other languages) you would achieve this effect.
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.
I have read that the main differences between classes and structures (other than functions), is that class members default to private, whereas structure members default to public.
That implies that structure members can be private. My question is: Can you have private structure members? And if you can, what is the purpose of using private members? How would you even access them?
Yes structures can have private members, you just need to use the access specifier for the same.
struct Mystruct
{
private:
m_data;
};
Only difference between structure and class are:
access specifier defaults to private for class and public for struct
inheritance defaults to private for class and public for struct
How can you access them?
Just like you access private members of a class. i.e: they can only be accessed within the structures member functions and not in derived structure etc.
The only difference between struct and class is default access (with the exception of some weird template situations, see Alf's comments below). This means you can access private members in the same way as in a class:
struct foo {
int get_X() { return x; }
void set_X(int x_) { x = x_; }
private:
int x;
};
Whether you use struct or class, then, is purely a matter of style. I tend to use struct when all members are public (eg, if it's a functor class with no member variables and only public functions).
One thing that makes this useful is that you can also use the friend key word in structs, so private members can only be used and modified by those specific functions or classes or what not that you want to be able to modify it. This way the user can't modify those sections themselves. They won't even show up in the auto fill features, at least in visual studio.
I'm having trouble understanding the difference between private and protected members in a C++ class. In simple terms, what is the difference?
protected members are accessible by derived classes. private members are not.
Generally (most of the time) members should either be private or public. It is rare and unusual to need a protected member (edit) in a well-designed system.
EDIT:
Maybe I should elaborate on why protected members can be a code-smell.
If derived classes have access to data members that other classes do not, this could be an indication that the base & derived classes are too tightly coupled. The derived classes have access to the base class' state, and therefore the base class' state is subject to corruption. If this were not the case, then there's also often no reason to just make the data members public.
Others have gone in to greater detail on this.
Here is what Stroustrup says in his text:
Members declared protected are far
more open to abuse than members
declared private . In particular,
declaring data members protected is
usually a design error. Placing
significant amounts of data in a
common class for all derived classes
to use leaves that data open to
corruption. Worse, protected data,
like public data, cannot easily be
restructured because there is no good
way of finding every use. Thus,
protected data becomes a software
maintenance problem.
See also this question.
From the C++ FAQ:
A member (either data member or member function) declared in a private section of a class can only be accessed by member functions and friends of that class
A member (either data member or member function) declared in a protected section of a class can only be accessed by member functions and friends of that class, and by member functions and friends of derived classes
A member (either data member or member function) declared in a public section of a class can be accessed by anyone
Protected members can be accessed by derived classes (and friends).
Private members can only be accessed by the declaring class (or by friends).
Simple example:
class Base
{
protected:
int prot;
private:
int priv;
public:
int Prot() const { return prot; }
int Priv() const { return priv; }
};
class Derived
{
public:
void ShowProt() { cout << prot; } // OK - prot is accessible because it is protected
void ShowPriv() { cout << priv; } // Compile Error - cannot access priv, which is private
void ShowPriv2() { cout << Priv(); } // OK, because Priv() is public
};
I was just going through some codes of C++.
Where in I came across the concept of reinterpret_cast operator.
EDIT 1 :
I know that accessing private members of a class is not recommended.
But in some situations we ought to go ahead and access them.
I have just put forth this question to get my concepts clear.
In the example that I referred,the private member of the Class is accessed by simply creating a structure with the same variables and then later on modified by implementing
reinterpret_cast operator.
I have understood the usage of reinterpret_cast operator,as in I know what it does,but I fail to understand how a structure could be used to modify the values of a private Class member.
Following is the source code which I referred:
Class:
class Student
{
public:
explicit Student(float percent) // Cannot be used for conversion
{
static int nid;
id = ++nid;
score = percent;
}
int Id() const
{
return id;
}
float GetScore() const
{
return score;
}
void SetScore(float value)
{
score = value;
}
virtual ~Student(){}
private:
int id;
float score;
};
Structure used to access and modify private class members:
struct _Student
{
void* vptr;
int id;
float score;
};
_Student* bs3 = reinterpret_cast<_Student*>(bs2);
bs3->id = 5;
Thank you.Please correct me if I'm wrong/I couldn't put forth my question in an appropriate manner.
$5.2.10/2 - "An expression of
integral, enumeration, pointer, or
pointer-to-member type can be
explicitly converted to its own type;
such a cast yields the value of its operand."
This means that pointers 'bs2' and 'bs3' are pointing to the same location
$9.2/16 - "Two standard-layout struct
(Clause 9) types are layout-compatible
if they have the same number of
non-static data members and
corresponding non-static data members
(in declaration order) have
layout-compatible types (3.9)."
This means that your class and struct are layout compatible.
$9/6-
A standard-layout class is a class
that:
— has no non-static data members
of type non-standard-layout class (or
array of such types) or reference,
— has no virtual functions (10.3) and no
virtual base classes (10.1),
— has the same access control (Clause 11) for
all non-static data members,
— has no non-standard-layout base classes,
— either has no non-static data members
in the most-derived class and at most
one base class with non-static data
members, or has no base classes with
non-static data members, and
— has no base classes of the same type as the
first non-static data member.108
Since your class has a virtual destructor, your class and struct are not standard layout classes.
However you have added a 'void *' data member to possibly take care of the 'vptr' (thereby possibly mimicking layout compatibility based on your particular compiler implementation)
In this case reinterpret_cast is used to interpret the class pointer (bs2) as a struct pointer (bs3). By default struct members are public. Since the return value of reinterpret cast points to the same memory (refer quote above) where class members are located, you can modify the struct members (which are the same as the original class members).
This is cheating. This is highly discouraged.! This is most likely going to lead to undefined behavior
But in some situations we ought to go ahead and access them.
And what, pray, are these situations?
Other than design errors, I can’t see any. Accessing private members is a no-go. If you need the access, then provide it by legal means, i.e. either make the members more accessible or use friend modifiers to access them in a controlled way.
Violating the C++ type checking system equals game over: you cheat the compiler, don’t expect it to work with you. With this kind of undefined behaviour (i.e. not just platform dependent but forbidden for good reasons) you’re just inviting trouble in the form of very hard to track bugs.
tl;dr: Don’t. Ever.
Caveat: There is one exception: you have a library that you cannot access/modify the source code of, and you have no way of influencing its interface design. And additionally you can be sure (how?) that it won’t ever change. In this case the only solution may be to hack the library with such tricks.
I think you should perhaps change the context of your question somewhat.
If you realize you need to access a private variable in your class then
you are facing a design problem that needs to be resolved instead of
hacked around using an unsafe type conversion. Even if it is just
hypothetical and for the sake of asking about reinterpret_cast here.
As for a use case of reinterpret_cast that makes sense I'd say inside a hash function:
unsigned short Hash( void *p )
{
unsigned int val = reinterpret_cast<unsigned int>( p );
return ( unsigned short )( val ^ (val >> 16));
}
Some links with useful info:
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
http://advancedcppwithexamples.blogspot.com/2010/02/reinterpretcast-in-c.html
http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter03_054.html
But in some situations we ought to go ahead and access them.
If you have to access them in any situation, change its access specification.
Or better, make a public method that would accept a token(or some special permissions - to validate the caller), and return the requested value.
What you've got there is a horrible hack around encapsulation. If you really want to access private variables then you should be using the "friend" keyword. The reason the reinterpret_cast works is because you're interpretting the bytes of class Student as the struct _Student - which has it's variables declared as public by default. There are all manner of bad ways to access the private data, here's another one I can think of:
int* bs3 = reinterpret_cast<int*>(bs2);
++bs3;
*bs3 = 5;
Just don't do it would be my advice.