Why do classes in C++ have to declare their private functions? Has it actual technical reasons (what is its role at compile time) or is it simply for consistency's sake?
I asked why private functions had to be declared at all, as they don't add anything (neither object size nor vtable entry) for other translation units to know
If you think about it, this is similar to declaring some functions static in a file. It's not visible from the outside, but it is important for the compiler itself. The compiler wants to know the signature of the function before it can use it. That's why you declare functions in the first place. Remember that C++ compilers are one pass, which means everything has to be declared before it is used.1
From the programmer's point of view, declaring private functions is still not completely useless. Imagine 2 classes, one of which is the friend of the other. The friendzoned class2 would need to know how the privates of that class look like, (This discussion is getting weird) otherwise they can't use it.
As to why exactly C++ was designed in this way, I would first say there is the historical reason: the fact that you can't slice a struct in C, was adopted by C++ so you can't slice a class (and adopted by other languages branched from C++, too). I'd also guess that it's about simplicity: Imagine how difficult it would be to devise a method of compilation in which you can split the class among different header files, let your source files know about it, and prevent others from adding stuff to your class.
A final note is that, private functions can affect vtable size. That is, if they are virtual.
1 Actually not entirely. If you have inline functions in the class, they can refer to functions later defined in the same class. But probably the idea started from single pass and this exception later added to it.
2 It's inlined member functions in particular.
You have to declare all members in the definition of the class itself so that the compiler knows which functions are allowed to be members. Otherwise, a second programmer could (accidentally?) come along and add members, make mistakes, and violate your object's guarantees, causing undefined behavior and/or random crashes.
There's a combination of concerns, but:
C++ doesn't let you re-open a class to declare new members in it after its initial definition.
C++ doesn't let you have different definitions of a class in different translation units that combine to form a program.
Therefore:
Any private member functions that the .cpp file wants declared in the class need to be defined in the .h file, which every user of the class sees too.
From the POV of practical binary compatibility: as David says in a comment, private virtual functions affect the size and layout of the vtable of this class and any classes that use it as a base. So the compiler needs to know about them even when compiling code that can't call them.
Could C++ have been invented differently, to allow the .cpp file to reopen the class and add certain kinds of additional member functions, with the implementation required to arrange that this doesn't break binary compatibility? Could the one definition rule be relaxed, to allow definitions that differ in certain ways? For example, static member functions and non-virtual non-static member functions.
Probably yes to both. I don't think there's any technical obstacle, although the current ODR is very strict about what makes a definition "different" (and hence is very generous to implementations in allowing binary incompatibilities between very similar-looking definitions). I think the text to introduce this kind of exception to the rule would be complex.
Ultimately it might come down to, "the designers wanted it that way", or it might be that someone tried it and encountered an obstacle that I haven't thought of.
The access level does not affect visibility. Private functions are visible to external code and may be selected by overload resolution (which would then result in an access violoation error):
class A {
void F(int i) {}
public:
void F(unsigned i) {}
};
int main() {
A a;
a.F(1); // error, void A::F(int) is private
}
Imagine the confusion when this works:
class A {
public:
void F(unsigned i) {}
};
int main() {
A a;
a.F(1);
}
// add private F overload to A
void A::F(int i) {}
But changing it to the first code causes overload resolution to select a different function. And what about the following example?
class A {
public:
void F(unsigned i) {}
};
// add private F overload to A
void A::F(int i) {}
int main() {
A a;
a.F(1);
}
Or here's another example of this going wrong:
// A.h
class A {
public:
void g() { f(1); }
void f(unsigned);
};
// A_private_interface.h
class A;
void A::f(int);
// A.cpp
#include "A_private_interface.h"
#include "A.h"
void A::f(int) {}
void A::f(unsigned) {}
// main.cpp
#include "A.h"
int main() {
A().g();
}
One reason is that in C++ friends can access your privates. For friends to access them, friends have to know about them.
Private members of a class are still members of the class, so they must be declared, as the implementation of other public members might depend on that private method. Declaring them will allow the compiler to understand a call to that function as a member function call.
If you have a method that only is used int the .cpp file and does not depend on direct access to other private members of the class, consider moving it to an anonymous namespace. Then, it does not need to be declared in the header file.
There are a couple of reason on why private functions must be declared.
First Compile Time Error Checks
the point of access modifiers is to catch certain classes (no pun intended) of programming errors at compile time. Private functions are functions that, if someone called them from outside the class, that would be a bug, and you want to know about it as early as possible.
Second Casting and Inheritance
Taken from the C++ standard:
3 [ Note: A member of a private base class might be inaccessible as an inherited member name, but accessible directly. Because of the rules on pointer conversions (4.10) and explicit casts (5.4), a conversion from a pointer to a derived class to a pointer to an inaccessible base class might be ill-formed if an implicit conversion is used, but well-formed if an explicit cast is used.
3rd Friends
Friends show each other there privates. A private method can be call by another class that is a friend.
4th General Sanity and Good Design
Ever worked on a project with another 100 developers. Having a standard and a general set of rule helps maintain maintainable. declaring something private has a specific meaning to everyone else in the group.
Also this flows into good OO design principles. What to expose and what not
Related
Following code prints "I'm B!". It's a bit strange because B::foo() is private. About A* ptr we can say that its static type is A (foo is public) and its dynamic type is B (foo is private). So I can invoke foo via pointer to A. But this way I have access to private function in B. Can it be considered as encapsulation violation?
Since access qualifier is not part of class method signature it can lead to such strange cases. Why does in C++ access qualifier is not considered when virtual function is overridden? Can I prohibit such cases? What design principle is behind this decision?
Live example.
#include <iostream>
class A
{
public:
virtual void foo()
{
std::cout << "I'm A!\n";
};
};
class B: public A
{
private:
void foo() override
{
std::cout << "I'm B!\n";
};
};
int main()
{
A* ptr;
B b;
ptr = &b;
ptr->foo();
}
You have multiple questions, so I'll try to answer them one-by-one.
Why is in C++ access qualifier not considered when virtual function is overridden?
Because access qualifiers are taken into account by the compiler after all overload resolutions.
Such behavior is prescribed by the Standard.
For example, see on cppreference:
Member access does not affect visibility: names of private and privately-inherited members are visible and considered by overload resolution, implicit conversions to inaccessible base classes are still considered, etc. Member access check is the last step after any given language construct is interpreted. The intent of this rule is that replacing any private with public never alters the behavior of the program.
The next paragraph described the behavior demonstrated by your example:
Access rules for the names of virtual functions are checked at the call point using the type of the expression used to denote the object for which the member function is called. The access of the final overrider is ignored.
Also see the sequence of actions listed in this answer.
Can I prohibit such cases?
No.
And I don't think you will ever be able to do so, because there's nothing illegal in this behavior.
What design principle is behind this decision?
Just to clarify: by "decision" here I imply the prescription for the compiler to check the access qualifiers after overload resolution.
The short answer: to prevent surprises when you're changing your code.
For more details let's assume you're developing some CoolClass which looks like this
class CoolClass {
public:
void doCoolStuff(int coolId); // your class interface
private:
void doCoolStuff(double coolValue); // auxiliary method used by the public one
};
Assume that compiler can do overload resolution based on public/private specifiers. Then the following code would successfully compile:
CoolClass cc;
cc.doCoolStuff(3.14); // invokes CoolClass::doCoolStuff(int)
// yes, this would raise the warning, but it can be ignored or suppressed
Then at some point you discover that your private member function is actually useful for the class client and move it to "public" area. This automatically changes the behavior of the preexisting client code, since now it invokes CoolClass::doCoolStuff(double).
So the rules of applying access qualifiers are written in a manner that does not allow such cases, so instead you will get the "ambiguous call" compiler error in the very beginning. And virtual functions are no special case for the same reason (see this answer).
Can it be considered as encapsulation violation?
Not really.
By converting pointer to your class into a pointer to its base class you're actually saying: "Herewith I would like to use this object B as if it's an object A" - which is perfectly legal, because the inheritance implies "as-is" relation.
So the question is rather, can your example be considered as violating contract prescribed by the base class? It seems that yes, it can.
See the answer to this question for alternative explanation.
P.S.
Don't get me wrong, all this doesn't mean at all that you shouldn't use private virtual functions. On the contrary, it's often considered as a good practice, see this thread. But they should be private from the very base class. So again, the bottom line is, you should not use private virtual functions to break public contracts.
P.P.S. ...unless you deliberately want to force client to use your class via the pointer to interface / base class. But there are better ways for that, and I believe the discussion of those lies beyond the scope of this question.
Access qualifiers like public, private, etc. are a compile time feature, while dynamic polymorphism is a runtime feature.
What do you think should happen at runtime when a private override of a virtual function is called? An exception?
Can it be considered as encapsulation violation?
No, since the interface is already published through the inheritance, it isn't.
It's perfectly fine (and might be intended), to override a public virtual function from the base class with a private function in the derived class.
Is there any semantic difference between the two in the title?
For example, I can write,
class Hi{
public:
static void Print(){
printf("hi\n");
}
};
but also,
namespace Hi{
inline void Print(){
printf("hi\n");
}
}
I'm of course assuming both of these definitions are in the header. Is it just a matter of style?
A main difference is that namespaces can be extended, while classes can be inherited. This difference was important for "enum wrappers" in C++03. Some people strongly favored wrapping enums in classes, and others strongly favored wrapping them in namespaces, while perhaps most didn't care and didn't wrap.
Namespaces support argument dependent lookup, while classes don't (except for calls of friend functions defined in class definitions, and then it's really namespace ADL kicking in).
Classes support access control (public, protected, private) while namespaces don't. With namespaces the technique corresponding to private access is a nested namespace called detail or impl or some such. But this is just convention, not something the compiler can check and enforce.
I guess that since the above is what occurred to me first, it's probably the most relevant.
Worth noting: libraries that uses classes as a kind of faux namespace mechanism do exist (in particular I ran into an XML parser library of that kind), but they are very rare, and I doubt that any new libraries do this except for possible the above mentioned enum wrapping, which however was made less important by the scoped enums of C++11.
Although the class in your first example serves as a makeshift namespace, the differences are not limited to style.
For example, static member functions get access to private members of the class, such as other static functions of the same class, private types defined inside the class, and private static variables defined inside the class.
You can emulate a lot of this behavior with namespaces and static non-member functions / variables defined in the scope of a translation unit. However, the emulation would not be complete when non-static members of the class need to share access to private members with static member functions. In this case you would need to provide additional functionality to expose private members to non-members, while member functions would get it for free.
Here is an example based on your code:
class Hi{
private:
// This static member variable is defined in a cpp file
static int count;
public:
Hi() { // Let's pretend concurrency does not exist
count++;
}
static void Print(){
printf("You said Hi %d times\n", count);
}
};
If you wanted to emulate the above behavior with namespaces, you would need to declare your Hi::Print a friend of a class, or provide a public function to get the current value of count.
Can I create a function inside a class without defining it in the header file of that class?
Why don't you try and see?
[˙ʇ,uɐɔ noʎ 'oᴎ]
Update: Just to reflect on the comments below, with the emphasis of the C++ language on smart compiling, the compiler needs to know the size of the class (thus requiring declaration of all member data) and the class interface (thus requiring all functions and types declaration).
If you want the flexibility of adding functions to the class without the need to change the class header then consider using the pimpl idiom. This will, however, cost you the extra dereference for each call or use of the function or data you added. There are various common reasons for implementing the pimpl:
to reduce compilation time, as this allows you to change the class without changing all the compilation units that depend on it (#include it)
to reduce coupling between a class' dependents and some often-changing implementation details of the class.
as Noah Roberts mentioned below the pimpl can also solve exception safety issues.
No. However, you can mimic such:
struct X
{
void f();
X();
~X();
private:
struct impl;
impl * pimpl;
};
// X.cpp
struct X::impl
{
void f()
{
private_function();
...
}
void private_function() { ...access private variables... }
};
//todo: constructor/destructor...
void X::f() { pimpl->f(); }
Short answer: No, you can't.
However, if you're trying to inject a private function into the class that will only be used in that class's implementation, you can create a function in an anonymous namespace within that class's .cpp file that takes an object of that type by reference or pointer.
Note that you won't be able to muck with the passed objects internal state directly (since there's no way for the class to declare friendship with that anonymous function), but if the function just aggregates operations from the public interface of the class it should work just fine.
No, you can't. It wouldn't make much sense anyway. How should users of your class that include the header file know about those functions and use them?
I have no idea what You are trying to do, but I have a strange gut feeling, that Pointer To Implementation (pImpl) idiom might be helpful. If you want to add a public method in a cpp file and that method is not declared in the class definition in a header, You can't do that and it doesn't make sense.
I want to access a private data member in a class. There is no member function in the class to access the private data member. It is private.
I want to take the class and some how crack it open. One method was to copy the declaration of the class, make the private member public and call the new class class something_else. Then I do a reinterpret cast and copy the original object. This works. But I want something more elegant ... or perhaps generic ... or just another way.
What options are there? Can I use void*? Can I memcpy the class into another empty class? What are ways to do this??
%
I am assuming that
You've already been through "breaking encapsulation is bad" stage,
Exhausted other possible solutions,
Can't change class' header.
There are a few ways to subvert access to a class's private members, as demonstrated in GotW #76.
Duplicate a class definition and add a friend declaration.
Use evil macros: #define private public before including class' header.
Write a class definition with identical binary layout and use reinterpret_cast to switch from original class to a fake one.
Specialize a template member function if there is one (the only portable solution).
With the idea you suggest in your question, you don't need to copy the original object. If you write your own "all public" variation of the real class declaration, then cast a pointer to that new type, you can directly access the object through it.
The reason why none of this is a good idea is simple. You must be manipulating objects of a class of which you don't control the source (otherwise you'd be able to modify the source to give you the access you need). But if you don't control the source, then what if the maintainers change the layout of their class? Your duplicated version will no longer match up, and there will be no way for the compiler to detect this mismatch. The result will probably be memory corruption at runtime.
Since it's incorrectly understood, I have to clarify. All the following solutions do not require you to recompile the object. To use a class in your code, if it's compiled into an object file, you should include header file with the declaration of that class.
#include <class.h>
ObjectFoo instance;
It is possible (but dangerous unless you're careful) to change the header (a) or copy the header to another place and include that header (b), without recompiling the class itself.
#include <class_fixed.h>
ObjectFoo instance;
Your code, where you included the new header will just think that within the object file (which you haven't recompiled!) he will find implementation of the class declared as in class_fixed.h. While there persists the class declared as in class.h. If you change offsets of members (add new members for example) in your new header, you're dead and the code will not work properly. But just changing the access works fine. Compiled code doesn't know about access, this matters only at the compilation strange.
This is not always harmful. In everyday life you encounter such a change when you install new version of a library into your system and do not recompile all programs that depend on it. But it should be handled with care
There are several solutions.
memcpy()Don't! Do not memcpy as object copying sometimes undergoes specific policy imposed by the class designer. For example, auto_ptrs can't be just memcopied: if you memcopy the auto_ptr and then destructor is ran for both, you'll attempt to free the same memory two times and the program will crash.
Change private: to public: in header or with macroIf your license permits it, you may solve your problem by editing the header file that comes with the implementation of the class. Whether the source code of the implementation (i.e. cpp-file of the class) is under your control doesn't matter: changing private to public for data members (in header) suffices and works just fine even if you're given a binary-only library that contains class definition. (For member functions changing access sometimes changes its internal name, but for MSVS and GCC it's ok.)
Adding a new getter functionWhile changing private to public is nearly always ok (unless you rely on specific compile-time checks that should break the compilation if class has certain member accessible), adding new getter function should be performed carefully. The getter function should be inline (and therefore defined in the header file of the class).
reinterpret_castThe cast works just fine if you're NOT casting a pointer to dynamic base class (dynamic means "with virtual functions or bases") whose actual instance at the moment of casting can be derived from the class at the particular piece of code.
protected:And just in case you forgot. C++ can declare members protected:, i.e. accessible only to the classes derived from the given. This may fulfill your needs.
You can, but you shouldn't. The objects are just memory. You can certainly cast the pointer into an equivalent class that has the same members but where everything is public. But why do you want to do this? Do you have somebody else's code that you need to work with? Get them to add proper accessor methods. Do you really need to treat them as public members? Change the class.
I'm not really sure what you are trying to do, but it's probably a mistake.
I agree with the "edit the source" comment, but I think you should add a method, not just comment out the 'private'.
You must have the declaration of the class, so you presumably have the header but possibly not the .cpp/whatever file. Add an inline member function to the class in a copy of the header, and include this header instead of the original. You should still be able to link to the object file for the inaccessible source code.
Of course this counts as an evil hack, bypassing the protections built into the language rather than working with them. That's why I suggest the minimally evil hack - don't make everything private, and if you can get away with a getter (but no setter) do that. Of course the real minimal evil is not to do it, if there's any way at all to avoid it.
Remember, if this is someone elses class you're working with, the next version might be implemented differently and might not have that member at all.
Thank you ... I did want to show the code for my original fix. The reason as someone aluded to is that I cannot change the original code ... so I have to do a jail break.
#include<iostream>
using namespace std;
// Class Objectfoo
// Pretend Objectfoo lives somewhere else ... I cannot open him up
class ObjectFoo
{
private:
int datax;
public:
ObjectFoo() { datax = 100; }
void get() { cout << datax << endl;}
};
// Class ObjectBar
class ObjectBar
{
public:
int datax;
};
ObjectFoo FOOEY;
ObjectBar* touch_foo(int x, ObjectFoo* foo , ObjectBar* bar)
{
bar = reinterpret_cast<ObjectBar*>(foo);
bar->datax = x;
return bar;
}
int main()
{
ObjectBar* bar;
cout << "Displaying private member in ObjectFoo i.e. ObjectFoo.datax" << endl;
FOOEY.get();
cout << "Changing private member " << endl;
bar = touch_foo(5, &FOOEY, bar);
cout << "bar->datax = " << bar->datax << endl;
cout << "Displaying private member in ObjectFoo i.e. ObjectFoo.datax" << endl;
FOOEY.get();
return 0;
}
This works ... but I think I want something more generic ... or more flexible.
%
I have a class with two member functions that share a piece of code:
void A::First()
{
firstFunctionEpilogue();
sharedPart();
}
void A::Second()
{
secondFunctionEpilogue();
sharedPart();
}
Currently firstFunctionEpilogue(), secondFunctionEpilogue() and sharedPart() are not function calls but just pieces of code, sharedPart() code being duplicated. I want to get rid of the duplication.
The shared piece of code doesn't need access to any members of the class. So I can implement it as any of the three:
a static member function,
a const non-static member function or
a local function.
Which variant is better and why?
If your function accesses state but does not change it then use a const member function.
Your case:
If it your function 1) doesn't need access to any member of the code, and 2) is related to that class, then make it a static function of your class.
That way it is clear that it is not modifying state, nor based on the state of the object.
An extra case you didn't mention:
There is another thing you can do too. And that is to make your SharedPart take in a member function pointer and to call it and then process it's main body. If you have a lot of First(), Second(), Third(), Fourth(), ... such functions then this can lead to less code duplication. That way you don't need to keep calling SharedPart(); at the end of each member function, and you can re-use First(), Second(), THird(), ... without calling the SharedPart() of the code.
I'd say:
It probably doesn't matter, so it's not so much "best practice" as "just don't do anything crazy".
If the class and all its members are defined in its header, then a private static member function is probably best, since it clearly indicates "not for clients". But there are ways to do this for a non-member function: don't document it, put in a comment "not for clients", and stick the whole thing in namespace beware_of_the_leopard.
If the class member functions are defined in a .cpp file, then little helper functions like this are best as free functions in the .cpp file. Either static, or in an anonymous namespace.
Or it could be in a different class.
Or, if it's a member, it could be virtual.
There are a lot of decisions, and I wouldn't stress out about it too much. Generally, I opt for a const non-static member function as a default unless I have a good reason not to do it that way.
Prefer static if clients need to call it without having an instance
Prefer local functions if you don't want to clutter the .h file or you want it completely hidden in the .c
Make it a non-member function
The shared piece of code doesn't need access to any members of the class.
As a general rule, if a piece of code doesn't need access to any members of the class don't make it a member function! Try to encapsulate your classes as much as possible.
I'd suggest doing a non-member function in a separate namespace that would call the public methods and then call the function you made for the shared code.
Here is an example of what I mean :
namepsace Astuff{
class A{...};
void sharedPart(){...};
void first(const A& a);
void second(const A& a);
}
void Astuff::first(const A& a){
a.first();
sharedPart();
}
a static member function, a const
non-static member function or a local
function.
Generally, it should be a member function of another class, or at least non-static member of the class itself.
If this function is only called from instance members of a class - probably its logical meaning requires an instance, even if syntax does not. Can anything except this object provide meaningful parameters or make use of the result?
Unless it makes sense to call this function from outside of the object instance, it shouldn't be static. Unless it makes sense to call this function without accessing your class at all, it shouldn't be local.
Borrowing examples from Brian's comment:
if this function changes global state, it should be member of a class of global state;
if this function writes to file, it should be member of a class of file format;
if it's refreshing screen, it should be member of... etc
Even if it's a plain arithmetic expression, it may be useful to make it a member (static or not) of some ArithmeticsForSpecificPurpose class.
Make it a non-member non-friend function. Scott Meyer's has a great explanation for this here (and also Item 23 of Effective C++ 3rd Edition).
As a rule of thumb "try to keep it as local as possible but as visible as necessary".
If all code calling the function resides in the same implementation file, this means keeping it local to the implementation file.
If you'd make it a private static method of your class, it would not be callable by implementaions including your class, but it would still be visible to them. So every time you change the semantics of that method, all implementaions including your calls will have to recompile - which is quite a burden, since from their point of view, they don't even need to know those sementics.
Thus, in order to minimize unnecessary dependencies, you would want to make it a static global function.
However, if you should ever find yourself repeating this global function in mulitple implementation files, it would be time to move the function into a seperate header/implementaion file pair, so that all callers can include it.
Whether you place that function into a namespace, at global scope, or as a static function in a class is really up to taste.
On a final note, if you go for the global static function, there's a "more c++ like" version: anonymous namespaces. It has the nice property that it can actually store state and also prevents users for being able to even forward declare any of its functions.
// in your .cpp file
namespace /*anonymous*/
{
void foo()
{
// your code here
}
};
void MyClass::FooUser1() { foo(); }
void MyClass::FooUser2() { foo(); }