If we have to declare proto type inside of public tag for class then what is the benefit of making functions outside of class
IMHO, there are mainly 2 reasons:
a matter of style:
Some of us prefere keeping individual blocks of code small. Putting the method definitions outside of the class definition helps in keeping the class definition small. You may or not agree on that.
separate compilation:
A common usage is to put the class definition in an include file to allow other compilation units to use it. As it will be included in several files, it will be compiled several times. So it can make sense on a performance build point of view to keep that include file small.
In addition, usages recommend to keep individual files in a projet small. If one is changed, only that one need to be compiled again and archived in a code version system. Splitting the class definition and its methods in 2 different files helps in that goal.
Anyway, both styles are allowed per the standard, and it has no impact on run time performance
Related
I have two functions, which are private members of class "Data":
class Date
{
private:
bool leapYear(int y);
void fillDate(int d, Month m, int y);
};
So, where is the best to define this functions:
in class definition;
in header file outside the class;
or in ".cpp" file?
You have the choice here. Here are some ideas to make your mind:
Inlining for speed is no longer a concern, since compilers are now good at link time optimization. So performance should not be a decision factor here (compilation speed matters too, but this is another bag of worms).
Small inline member functions, defined inside the class, may be an easy way to "document" what the class does. Also, this tends to keep the implementation localized, which is comfortable when reading the code. Don't overdo it however.
Large functions should in principle go into their own file, or at least outside the class definition, since they clutter the class definition code for no good reason. Template code is no exception.
Pimpl have advantages/disadvantages too, but here I don't see any good reason to introduce such beasts in your simple case. They are used typically to reduce dependencies between header files.
Here, if the implementation is small, you can write the code inline, inside the class. But you should put them in their own implementation (".cpp") file, if the logic is complex.
You can also start inline, and when the code has settled to something more complex, move the implementation to its own file.
I strongly discourage you to consider option 2. This gets you "Multiple definition" error by the linker if you include this file in more than one implementation file, because the definition will be copied (by the preprocessor) to each .cpp file.
My personal philosophy about this is to put all function definitions into the implementation (.cpp) file, because, first of all, it separates declarations (+ documentation) from definitions which adds to code clarity IMO, and, secondly, having all definitions in one place (the implementation file) makes it easier for me to find functions. In my experience it was always quite a nuisance to have to switch between header and implementation files to see whether this particular function I'm looking for was inlined / defined in the header or if it was in the implementation file. Having all function definitions in the implementation file means I know I will find the definition of any function in that file, and won't have to waste time switching and looking around.
For now I do not use header files at all. Classes are each in a single .cpp file completely. But to save compile time I want to make use of header files now. My hope is that Visual Studio won't compile classes which weren't modified for debug builds then.
Is there a way to mention only public methods and members in the header file. In theory that would be enough information for the compiler. If another file, say main.cpp includes the class header there is no need for private methods and members, is it?
How can I use header files without retyping the names of private methods and members? The reasons for me to want so is coding productivity. When I want do add a small helper function to the class used by another method, I don't want to have to also add it's signature to the header file.
If another file, say main.cpp includes the class header there is no need for private methods and members, is it?
No, public methods and members aren't necessarily enough. For example, if another .cpp file were to try and create an instance of your class:
SomeClass instance;
the compiler will need to know, among other things, how much memory to allocate for SomeClass. For that it requires full knowledge of SomeClass's private data members.
The way you are framing the question makes it sound as if you were intent on fighting the language. I don't think that's a good way to go about it. I think the best way is to do things the way things are usually done in the language of your choice, and depart from that only when there is a specific, clearly understood need.
The way things are usually done in C++ is that the entire class declaration goes in the header file, and the definition is in some way split between the header file and the corresponding .cpp file. The exact split is determined by various technical considerations. For example, templates and inline functions normally have to appear in the header file. On the other hand, placing code in header files increases dependencies and potentially build times.
There are ways to address these issues. However, since this involves extra complexity, I'd argue that this should only be done if there is a clearly identifiable need.
I don't know of a way to do what you're asking, but there is another way to give some isolation. You might want to take a look at the pimpl idiom as it offers isolation about private information. It's a little bit of extra work, but it can be extremely useful, especially in large projects.
All function declarations should go in header files and all function definitions should go in cpp files. It's not good coding practice to put declarations inside the cpp files.
You could put definitions inside headers though, when you write templates or inline functions.
Once you declare the class in the header file, you have to declare all its methods and members inside the class' declaration in the header, given that your class is no longer declared in the cpp file.
Most C++ class method signatures are duplicated between the declaration normally in a header files and the definition in the source files in the code I have read. I find this repetition undesirable and code written this way suffers from poor locality of reference. For instance, the methods in source files often reference instance variables declared in the header file; you end up having to constantly switch between header files and source files when reading code.
Would anyone recommend a way to avoid doing so? Or, am I mainly going to confuse experienced C++ programmers by not doing things in the usual way?
See also Question 538255 C++ code in header files where someone is told that everything should go in the header.
There is an alternative, but the cure is worse than the illness — define all the function bodies in the header, or even inline in the class, like C#. The downsides are that this will bloat compile times significantly, and it'll annoy veteran C++ programmers. It can also get you into some annoying situations of circular dependency that, while solvable, are a nuisance to deal with.
Personally, I just set my IDE to have a vertical split, and put the header file on the right side and the source file on the left.
I assume you're talking about member function declarations in a header file and definitions in source files?
If you're used to the Java/Python/etc. model, it may well seem redundant. In fact, if you were so inclined, you could define all functions inline in the class definition (in the header file). But, you'd definitely be breaking with convention and paying the price of additional coupling and compilation time every time you changed anything minor in the implementation.
C++, Ada, and other languages originally designed for large scale systems kept definitions hidden for a reason--there's no good reason that the users of a class should have to be concerned with its implementation, nor any reason they should have to repeatedly pay to compile it. Less of an issue nowadays with faster systems, but still relevant for really large systems. Additionally, TDD, stubbing and other testing strategies are facilitated by the isolation and quicker compilation.
Don't break with convention. In the end, you will make a ball of worms that doesn't work very well. Plus, compilers will hate you. C/C++ are setup that way for a reason.
C++ language supports function overloading, which means that the entire function signature is basically a way to identify a specific function. For this reason, as long as you declare and define function separately, there's really no redundancy in having to list the parameters again. More precisely, having to list the parameter types is not redundant. Parameters names, on the other hand, play no role in this process and you are free to omit them in the declaration (i.e in the header file), although I belive this limits readability.
You "can" get around the problem. You define an abstract interface class that only contains the pure virtual functions that an outside application will call. Then in the CPP file you provide the actual class that derives from the interface and contains all the class variables. You implement as normal now. The only thing this requires is a way to instantiate the derived implementation class from the interface class. You could do that by providing a static "Create" function that has its implementation in the CPP file.
ie
InterfaceClass* InterfaceClass::Create()
{
return new ImplementationClass;
}
This way you effectively hide the implementation from any outside user. You can't, however, create the class on the stack only on the heap ... but it does solve your problem AND provides a better layer of abstraction. In the end though if you aren't prepared to do this you need to stick with what you are doing.
Background
I have an abstract class, something like
class IConverter{
public:
virtual void DoConvertion() = 0;
};
There will be many concrete classes which just implements DoConvertion method.
class TextConverter : public IConverter{
public:
virtual void DoConvertion(){
// my code goes here
}
};
class ImageConverter : public IConverter{
public:
virtual void DoConvertion(){
// my code goes here
}
};
There will be many concrete implementation like this. I have created a header file say, CharacterConverter.h which has the abstract class IConverter.
Question
Since my concrete classes just implement the DoConvertion method, is it required to create separate header files for each concrete class? I mean is it required to create ImageConverter.h, TextConverter.h and so on for all concrete classes? All these header files is going to contain the same code like IConverter abstract class.
Any thoughts?
It is not required. It's basically a judgment call.
If the implementation is simple for each class you can put them all in one .h and one .cpp
If the implementations are a bit longer, then it's probably cleaner to use a separate .h and .cpp file for each.
Some advantages of using a different .h/.cpp for each class:
It will keep the code organized and clean
Reduced compiling work: A change in one of the implementations won't need to recompile all others
Faster compiling time: Several compilers can compile multiple files at once such as Visual Studio's /MP switch. With several files you'll have a faster compile time.
Other files can include only what they need instead of everything
Faster link time: Linking time will be reduced due to incremental linking
Using version control you can look back on only the changes to a particular derived class, instead of having to go through all changes made to the massive 1 .h/.cpp file to find that one change in a particular derived class.
One of the main points of creating an interface class is so that clients can be depend on the abstract interface rather than the concrete implementation, and you are then free to change the implementation without impacting clients.
Putting the concrete declarations in the same header files as the interface declarations defeats this, so now if you change an implementation detail of a concrete class, your clients would need to re-compile.
Something you might consider, depending on the rest of your design, is a factory, where your abstract class has a static method (or multiple static methods, depending on how you implement it) that constructs the appropriate subclass and returns it as an IConverter*. With this, you can expose only the abstract definition in the header file, and have all the concrete class definitions and implementations in a single .cpp file along with the super class implementation. This gets a bit unwieldy if your subclass are large, but with smaller classes it reduces the number of files you have to manage.
But, as others have pointed out, it's ultimately a judgment call. The only performance issues would be related to compiling; more cpp files might take (slightly) longer to compile and more header files might increase dependency analysis. But there's no requirement that every header file have a matching cpp and vice verse.
Based on the comments, I'd recommend a structure like this:
IConverter.h ==> definition of IConverter
Converters.h ==> definitions of all subclasses
IConverter.cpp ==> include IConverter.h and Converters.h, contain implementation of IConverter abstract functionality (static factory method and any inheritable functionality)
TextConvter.cpp, ImagerConverter.cpp, etc. ==> seperate cpp files for each subclass, each containing IConverter.h and Converters.h
This allows you to only include the IConverter.h in any clients that use the factory and generic functionality. Putting all the other definitions in a single header allows you to consolidate if they're all basically the same. Separate cpp files allow you to take advantage of the compiler benefits mentioned by Brian. You could inline the subclass definitions in header files as mentioned, but that doesn't really buy you anything. Your compiler is usually smarter than you are when it comes to optimizations like inline.
You'll probably get answers both ways.
I'd say, for any trivial converters, having all of them in a single .h/.cpp pair is sufficient and that it's overkill to split every one into a single pair. I think the tradeoff of maintenance of lots of files vs. maintenance of a bunch of methods within a single file is worth it in this case.
Complex conversions probably deserve their own file pairs.
You will need definitions of the concrete classes to create objects, so you'll need to put those definitions into a .h file somewhere. Which file you put them in is up to you.
The best answer to this is what's easier to read. One long source file is going to be difficult for you and other programmers to follow. On the other hand, many tiny (half screen-full) source files is just as bad.
You'd probably be better off using factories or function pointers.
However, one particularly nasty way that springs to mind is using a macro to declare your concrete classes. For example:
At the bottom of IConverter.h include the following macro
#define DECLARE_CONVERTER_CLASS(CLASS_NAME) \
class CLASS_NAME : public IConverter\
{ \
public: \
CLASS_NAME() {} \
virtual void DoConversion(); \
}; \
Then in MyConverter1.cpp
DECLARE_CONVERTER_CLASS(MyConverter1)
virtual void MyConverter1::DoConversion()
{
...
}
Yuck :-)
I am fairly new to C++ and I have seen a bunch of code that has method definitions in the header files and they do not declare the header file as a class. Can someone explain to me why and when you would do something like this. Is this a bad practice?
Thanks in advance!
Is this a bad practice?
Not in general. There are a lot of libraries that are header only, meaning they only ship header files. This can be seen as a lightweight alternative to compiled libraries.
More importantly, though, there is a case where you cannot use separate precompiled compilation units: templates must be specialized in the same compilation unit in which they get declared. This may sound arcane but it has a simple consequence:
Function (and class) templates cannot be defined inside cpp files and used elsewhere; instead, they have to be defined inside header files directly (with a few notable exceptions).
Additionally, classes in C++ are purely optional – while you can program object oriented in C++, a lot of good code doesn't. Classes supplement algorithms in C++, not the other way round.
It's not bad practice. The great thing about C++ is that it lets you program in many styles. This gives the language great flexibility and utility, but possibly makes it trickier to learn than other languages that force you to write code in a particular style.
If you had a small program, you could write it in one function - possibly using a couple of goto's for code flow.
When you get bigger, splitting the code into functions helps organize things.
Bigger still, and classes are generally a good way of grouping related functions that work on a certain set of data.
Bigger still, namespaces help out.
Sometimes though, it's just easiest to write a function to do something. This is often the case where you write a function that only works on primitive types (like int). int doesn't have a class, so if you wanted to write a printInt() function, you might make it standalone. Also, if a function works on objects from multiple classes, but doesn't really belong to one class and not the other, that might make sense as a standalone function. This happens a lot when you write operators such as define less than so that it can compare objects of two different classes. Or, if a function can be written in terms of a classes public methods, and doesn't need to access data of the class directly, some people prefer to write that as a standalone function.
But, really, the choice is yours. Whatever is the most simple thing to do to solve your problem is best.
You might start a program off as just a few functions, and then later decide some are related and refactor them into a class. But, if the other standalone functions don't naturally fit into a class, you don't have to force them into one.
An H file is simply a way of including a bunch of declarations. Many things in C++ are useful declarations, including classes, types, constants, global functions, etc.
C++ has a strong object oriented facet. Most OO languages tackle the question of where to deal with operations that don't rely on object state and don't actually need the object.
In some languages, like Java, language restrictions force everything to be in a class, so everything becomes a static member function (e.g., classes with math utilities or algorithms).
In C++, to maintain compatibility with C, you are allowed to declare standalone C-style functions or use the Java style of static members. My personal view is that it is better, when possible, to use the OO style and organize operations around a central concept.
However, C++ does provide the namespaces facilities and often it is used in the same way that a class would be used in those situations - to group a bunch of standalone items where each item is prefixed by the "namespace" name. As others point out, many C++ standard library functions are located this way. My view is that this is much like using a class in Java. However, others would argue that Java uses classes because it doesn't have namespaces.
As long as you use one or the other (rather than a floating standalone non-namespaced function) you're generally going to be ok.
I am fairly new to C++ and I have seen a bunch of code that has method definitions in the header files and they do not declare the header file as a class.
Lets clarify things.
method definitions in the header files
This means something like this:
file "A.h":
class A {
void method(){/*blah blah*/} //definition of a method
};
Is this what you meant?
Later you are saying "declare the header file". There is no mechanism for DECLARING a file in C++. A file can be INCLUDED by witing #include "filename.h". If you do this, the contents of the header file will be copied and pasted to wherever you have the above line before anything gets compiled.
So you mean that all the definitions are in the class definition (not anywhere in A.h FILE, but specifically in the class A, which is limited by 'class A{' and '};' ).
The implication of having method definition in the class definition is that the method will be 'inline' (this is C++ keyword), which means that the method body will be pasted whenever there is a call to it. This is:
good, because the function call mechanism no longer slows down the execution
bad if the function is longer than a short statement, because the size of executable code grows badly
Things are different for templates as someone above stated, but for them there is a way of defining methods such that they are not inline, but still in the header file (they must be in headers). This definitions have to be outside the class definition anyway.
In C++, functions do not have to be members of classes.