Why is inheritance not implicitly defined - c++

This may have been answered before, but I couldn't find the words.
I'm trying to wrap my head around inheritance in C++, but coming from C# I can't seem to understand the reasoning behind the following case:
Foo.h
class Foo {
virtual void DoSomething();
}
class Bar : Foo { }
Bar.cpp
#include "Foo.h"
void Bar::DoSomething()
{
//Compiler error C2509 - member function not declared in 'Bar'
}
Since DoSomething is a pure virtual function, wouldn't it stand to reason that it would implicitly be declared as part of Bar?
If I have a lot of different classes inheriting from Foo, do I really need to explicitly declare DoSomething in each one of them?
What other constructs exist in C++ to handle this case?

C++ language is built on the same principles of independent translation as C. This means that all translation units in C++ program should be compilable completely independently of each other. They are linked into the final program later, when the compiler proper has already finished working.
In case of classes, in order to be able to compile each translation unit independently the compiler must be able to build a sufficiently complete understanding of what the given class is by seeing the definition of the class alone, i.e. the part that is usually placed in header files. While compiling one translation unit, the compiler has to know that DoSomething is overriden in Bar and that the definition for void Bar::DoSomething() exists somewhere, in some other translation unit. In order to achieve that the class definition must include declarations for all class member functions.
Your reasoning about "pure virtual function" is completely unclear to me. Firstly, it is not pure in your code sample (apparently you simply forgot the = 0 part). Secondly, just because the base class function is pure does not mean that the derived class function should be non-pure. It is quite possible that Bar was also supposed to be an abstract class. It is matter of your intent, which the compiler does not know.

The definition of Bar is all most code is going to know about it. Other translation units will not see "Bar.cpp" but are still going to need to generate the correct in-memory representation of Bar instances, including Bar's vtable. That means they need to know whether or not Bar is really overriding Foo::DoSomething or not, because the in-memory representation differs depending on that.

Yes, you do need to explicitly declare this method. Coming from C#, you'll notice that C++ does not 'hold your hand' through a lot of things. I don't mean that insultingly, but C++ forces you to be incredibly explicit in everything you do.

Related

Can I use a slim version of my header to be included with the library?

What I mean is my real header file can look like this:
#include "some_internal_class.h"
class MyLibrary {
Type private_member;
void private_function();
public:
MyLibrary();
void function_to_be_called_by_library_users();
};
Now I want to produce a dynamic library containing all the necessary definitions. and I want to ship with it a single header instead of shipping every single header I have in my library.
So I was thinking I could create a slim version of my header like so:
class MyLibrary {
public:
MyLibrary();
void function_to_be_called_by_library_users();
};
Headers are just declarations anyway right? they're never passed to the compiler. And I've declared what the user will be using.
Is that possible? If not, why not?
This is a One Definition Rule violation. The moment you deviate by a single token.
[basic.def.odr]/6
There can be more than one definition of a class type, [...] in a
program provided that each definition appears in a different
translation unit, and provided the definitions satisfy the following
requirements. Given such an entity named D defined in more than one
translation unit, then
each definition of D shall consist of the same sequence of tokens; and
Your program may easily break if you violate the ODR like that. And your build system isn't at all obligated to even warn you about it.
You cannot define a class twice. It breaks the One Definition Rule (ODT). MyLibrary does that, unfortunately.
they're never passed to the compiler
They will. Members of a class must be known at compile time, so that the compiler can determine the class's size.
Header are just declarations anyway right? they're never passed to the
compiler. And I've declared what the user will be using.
No. Headers are part of source code and are compiled together with source files. They contain the information necessary for a compiler to understand how to work with code (in your case, with class MyLibrary).
As an example, you want library users to be able to create objects of class MyLibrary, so you export the constructor. However, this is not sufficient: the compiler needs to know the size of the object to be created, which is impossible unless you specify all the fields.
In practice, deciding what to expose to library users and what to hide as implementation details is a hard question, which requires detailed inspection of the library usage and semantics. If you really want to hide the class internals as implementation detail, here are some common options:
The pimpl idiom is a common solution. It enables you to work with the class as it is usually done, but the implementation details are nicely hidden.
Extract the interface into an abstract class with virtual functions, and use pointers (preferably smart pointers) to work with the objects.
Headers are just declarations anyway right? they're never passed to the compiler.
The moment you do a #include to a file, its content are copied and pasted into your source file exactly as they are.
So even though you don't pass them directly as compiler arguments, they're still part of your code and code in them will be compiled into your translation units.
Solutions by #lisyarus are pretty good.
But another option would be doing it the C way. Which is the most elegant in my opinion.
In C you give your users a handle, which will most likely be a pointer.
Your header would look something like this:
struct MyLibrary;
MyLibrary*
my_library_init();
void
my_library_destroy(MyLibrary*);
void
my_library_function_to_be_called_by_library_users(MyLibrary*);
A very small and simple interface that does not show your users anything you don't want them to see.
Another nice perk is that your build system will not have to recompile your whole program just because you added a field to the MyLibrary struct.
You have to watch out though, because now you have to call my_library_destroy which will carry the logic of your destructor.

c++ - Use of header/source files to separate interface and implementation

In C++, classes are usually declared like this:
// Object.h
class Object
{
void doSomething();
}
// Object.cpp
#include "Object.h"
void Object::doSomething()
{
// do something
}
I understand that this improves compile time because having the class in one file makes you recompile it whenever you change either the implementation or the interface (see this).
However, from and OOP point of view, I don't see how separating the interface from the implementation helps. I've read a lot of other questions and answers, but the problem I have is that if you define the methods for a class properly (in separate header/source files), then how can you make a different implementation? If you define Object::method in two different places, then how will the compiler know which one to call? Do you declare the Object::method definitions in different namespaces?
Any help would be appreciated.
If you want one interface and multiple implementations in the same program then you use an abstract virtual base.
Like so:
class Printer {
public:
virtual void print_string(const char *s) = 0;
virtual ~Printer();
};
Then you can have implementations:
class EpsonPrinter : public Printer {
public:
void print_string(const char *s) override;
};
class LexmarkPrinter : public Printer {
public:
void print_string(const char *s) override;
};
On the other hand, if you are looking at code which implements OS independence, it might have several subdirectories, one for each OS. The header files are the same, but the source files for Windows are only built for Windows and the source files for Linux/POSIX are only built for Linux.
However, from [an] OOP point of view, I don't see how separating the interface from the implementation helps.
It doesn't help from an OOP point of view, and isn't intended to. This is a text inclusion feature of C++ which is inherited from C, a language that has no direct support for object-oriented programming.
Text inclusion for modularity is a feature borrowed, in turn, from assembly languages. It is almost an antithesis to object-oriented programming or basically anything that is good in the area of computer program organization.
Text inclusion allows your C++ compiler to interoperate with ancient object file formats which do not store any type information about symbols. The Object.cpp file is compiled to this object format, resulting in an Object.o file or Object.obj or what have you on your platform. When other parts of the program use this module, they almost solely trust the information that is written about it in Object.h. Nothing useful emanates out of the Object.o file except for symbols accompanied by numeric information like their offsets and sizes. If the information in the header doesn't correctly reflect Object.obj, you have undefined behavior (mitigated, in some cases, by C++'s support for function overloading, which turns mismatched function calls into unresolving symbols, thanks to name mangling).
For instance if the header declares a variable extern int foo; but the object file is the result of compiling double foo = 0.0; it means that the rest of the program is accessing a double object as an int. What prevents this from happening is that Object.cpp includes its own header (thereby forcing the mismatch between the declaration and definition to be caught by the compiler) and that you have a sane build system in place which ensures that Object.cpp is rebuilt if anything touches Object.h. If that check is based on timestamps, you must also have a sane file system and version control system that don't do wacky things with timestamps.
If you define Object::method in two different places, then how will the compiler know which one to call?
It won't, and in fact you will be breaking the "One Definition Rule" if you do this, which results in undefined behavior, no diagnostic required, according to the standards.
If you want to define multiple implementations for a class interface, you should use inheritance in some way.
One way that you might do it is, use a virtual base class and override some of the methods in different subclasses.
If you want to manipulate instances of the class as value types, then you can use the pImpl idiom, combined with virtual inheritance. So you would have one class, the "pointer" class, which exposes the interface, and holds a pointer to an abstract virtual base class type. Then, in the .cpp file, you would define the virtual base class, and define multiple subclasses of it, and different constructors of the pImpl class would instantiate different of the subclasses as the implementation.
If you want to use static polymorphism, rather than run-time polymorphism, you can use the CRTP idiom (which is still ultimately based on inheritance, just not virtual inheritance).

C++ Declaration of class variables in header or .cpp?

So far, I've been using classes the following way:
GameEngine.h declares the class as follows
class GameEngine {
public:
// Declaration of constructor and public methods
private:
InputManager inputManager;
int a, b, c;
// Declaration of private methods
};
My GameEngine.cpp files then just implement the methods
#include "____.h"
GameEngine::GameEngine() {
}
void GameEngine::run() {
// stuff
}
However, I've recently read that variable declarations are not supposed to be in the header file. In the above example, that would be an inputManager and a, b, c.
Now, I've been searching for where to put the variable declarations, the closest answer I found was this: Variable declaration in a header file
However, I'm not sure if the use of extern would make sense here; I just declare private variables that will only be used in an instance of the class itself. Are my variable declarations in the header files fine? Or should I put them elsewhere? If I should put them in the cpp file, do they go directly under the #include?
Don't confuse a type's members with variables. A class/struct definition is merely describing what constitutes a type, without actually declaring the existence of any variables, anything to be constructed on memory, anything addressable.
In the traditional sense, modern class design practices recommend you pretend they are "black boxes": stuff goes in, they can perform certain tasks, maybe output some other info. We do this with class methods all the time, briefly describing their signature on the .h/.hpp/.hxx file and hiding the implementation details in the .cpp/.cc/.cxx file.
While the same philosophy can be applied to members, the current state of C++, how translation units are compiled individually make this way harder to implement. There's certainly nothing "out of the box" that helps you here. The basic, fundamental problem is that for almost anything to use your class, it kind of needs to know the size in bytes, and this is something constrained by the member fields and the order of declaration. Even if they're private and nothing outside the scope of the type should be able to manipulate them, they still need to briefly know what they are.
If you actually want to hide this information to outsiders, certain idioms such as PImpl and inlined PImpl can help. But I'd recommend you don't go this way unless you're actually:
Writing a library with a semi-stable ABI, even if you make tons of changes.
Need to hide non-portable, platform-specific code.
Need to reduce pre-processor times due to an abundance of includes.
Need to reduce compile times directly impacted by this exposure of information.
What the guideline is actually talking about is to never declare global variables in headers. Any translation unit that takes advantage of your header, even if indirectly, will end up declaring its own global variable as per header instructions. Everything will compile just fine when examined individually, but the linker will complain that you have more than one definition for the same thing (which is a big no-no in C++)
If you need to reserve memory / construct something and bind it to a variable's name, always try to make that happen in the source file(s).
Class member variables must be declared in the class definition, which is usually in a header file. This should be done without any extern keywords, completely normally, like you have been doing so far.
Only variables that are not class members and that need to be declared in a header file should be declared extern.
As a general rule:
Variables that are to be used with many functions in the same class go in the class declaration.
Temporary variables for individual functions go in the functions themselves.
It seems that InputManager inputManager; belongs in the class header.
int a, b, c; is harder to know from here. What are they used for? They look like temporary variables that would be better off in the function(s) they're used in, but I can't say for sure without proper context.
extern has no use here.

C++: Why must private functions be declared?

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

Member function definition

What is the right approach to take:
Define the member (class) function inside the class?
Define the member (class) function outside the class?
Thanks.
Assuming you're talking about these three possibilities:
Method defined in class definition in header file.
Method define outside class definition in header file.
Method define outside class definition in implementation file.
Then project and company guidelines may force you to use (1) or (3) always.
When you have a choice, it's IMHO best to adapt to circumstances at hand, considering things such as
Do you want a header-only module? Then (1) as default, (2) possible.
Is the method a large beast? Then (2) or (3).
Template method specialization? Then (2) or (3).
There is a build-time problem (slow builds)? Indicates (3).
Template class? (1) or possibly (2)
But except where the choice is effectively forced on you, above all consider the clarity of your code.
Cheers & hth.,
A common advice is to keep headers as simple and clean as possible. Headers will be included by external code, and they will have to process everything that you have written there. If you write a method in the header, all translation units will compile that function, only so that the linker can discard all but one of them later on.
If your code has an internal dependency on a type or library that is not part of your interface, then by inlining the code of the member function in the class declaration the definition of that class or the headers of that library will have to be included in your header, and that means that you are leaking your implementation details to your users.
Unless the member function definition is trivial (in an informal sense) and doesn't introduce any additional dependencies I would normally define a member function outside of the class body in a separate source file.
It's often a matter of style but there are some cases in which it is necessary and many other cases in which it is desirable to define function outside of the class body.
For example, in the cases where you have interdependent classes and only a forward declaration of another class can be made available before the class definition, a member function which uses the definition of that other class can only be defined outside of the class body after a full definition of the other class has been provided.
Do you mean "in the class declaration / .h file" vs "in a .cpp file using ::" ?
If so I always go for the latter. When it comes to debugging, it's a lot easier to step through and see what's going on. It also helps declutter the class declaration, which doesn't need to know any implementation details"
If you want to define a function within a class the most basic syntax looks generally like:
class Object
{
int property;
void doSomething()
{
property=100;
}
};
If you want to define a function outside it is similar to declaring functions before main and in library files. In your class you have:
class Object
{
int property;
void doSomething();
};
Then somewhere after your class, after the main() function or in an included file you can have the definition:
void Object::doSomething()
{
property=100;
}
Some place classes in a header file and the definitions in a cpp file used by that header. Various techniques possible.
Both of these approaches are valid. Often I will include very small and/or core class functionality directly within the class and other functions which do heavier bulk work I tend to separate. Try to think the difference in coming upon your code and wanting to alter it.
if we see according to performance issue than it is more effective way to declare the function in the class . becouse at the compile time it conects all the funcation calls and other components so it will easy and must be faster to get all in one source...