Proper C++ header file?

Started by
25 comments, last by Clobslee 9 years, 5 months ago
(Only replying to some comments - rest of the stuff snipped out)

Declare the default constructor. Even though a default is provided, it is a really, really good habit to get into.


Only if your type has a default state that makes sense and doesn't violate invariants.

For the next few, I suggest reading up on the Rule of Zero

Declare the copy constructor. It will save you later. I would also (maybe) suggest looking into the concept of "non copyable".


Incorrect. Classes that don't deal with resources don't need one (and can use the default). Classes that do deal with resources should ONLY deal with resources.

Non-copyable however is a very valuable technique smile.png

Declare the default destructor. Even though a default is provided, it is a life saving habit to get into.


See above - don't write one unless you're making a resource managing class.

Again, one (assignment operator) is provided, but quite honestly, this is a another life saving habit to get into when you are just starting out.


See above - don't write one unless you're making a resource managing class.

If you are aiming for well performing code I would recommend doing away with the use of std::string all together and using const char*. Supplying a const char* in the "create" function should also lead you onto topics such as "copy on write", which is something totally worth reading about: (But not until you know why you shouldn't have a function operator in a class declaration smile.png ).
http://en.wikipedia.org/wiki/Copy-on-write


Disagree. std::string is perfect for managing strings and is fast for what it does. New programmers should use it and should avoid const char* if possible. If you take strings as parameters into functions then the caller only has to make the string once and pass it in rather then the caller having a string, pulling the buffer out to make it a const char*, and then the parameter doing a whole new allocation to store it in a string again.

"Copy on write" is another very bad idiom that has been explicitly forbidden in the C++11 standard because it provides unpredictable performance problems and massive threading headaches.

Finally, anything done "for well performing code" should only be done after your profiler tells you what is slow. Make sure your code works and is maintainable first, using standard libraries and algorithms. Only when your profiling tools prove to you that it's too slow should you even remotely consider "tricks" or doing things by hand.
Advertisement

Okay.. that means following standards their teachers set them. What I'm writing is an application of good programming standards, not commonly followed standards. I certainly wouldn't recommend everyone go around throwing macros in everything just because a student comes in here with their teacher having asked for some giant macro horror page for their next assignment.


Just to clarify, I wasn't refering to the arbitrary stylistic standards that some institutions expects students to adhere to, but actual official standards (ie ISO).


I certainly appreciate the point you're trying to make, but I'm also trying to make one that we shouldn't just go "Okay, everyone do it the old fashioned way."

What I'm hoping people will be able to take away from this, is that there are two ways this can be done - one which should always be good enough and which most compilers will support, and one which is the official sanctioned method which is universally supported (at least by standards compliant compilers). Which should be used is up to the individuals needs.

I asked a very reliable source (Bjarne Stroustrup via email [Got PM asking me to cite "reliable source"]) for his view of #pragma once. His reply was:

It's a useful hack. I would have supported it had I not know that serious
work is being done on modules. It is not portable.

Sounds like it is better to do a little more typing and simply do:


#ifndef HEADER_FILENAME_H
#define HEADER_FILENAME_H

// ... code ...

#endif // HEADER_FILENAME_H

I asked a very reliable source (Bjarne Stroustrup via email [Got PM asking me to cite "reliable source"]) for his view of #pragma once. His reply was:

It's a useful hack. I would have supported it had I not know that serious
work is being done on modules. It is not portable.

Sounds like it is better to do a little more typing and simply do:


#ifndef HEADER_FILENAME_H
#define HEADER_FILENAME_H

// ... code ...

#endif // HEADER_FILENAME_H

Its not portable because it's not part of the ISO/IEC standard. However MSVC, GCC, CLANG, Intel Compiler, and many other support it. Dunno why it is still not part of the standard, probably some member of the committee do not support it (maybe IBM XL C/C++ compiler?).

If you do not have any plans, even in dreams, to work with IBM stuffs at 99.98% you can use #pragma once. If a day you have to use IBM stuffs, just write a small program to automatically change the headers, it should not be such difficult.

"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/

Its not portable because it's not part of the ISO/IEC standard. However MSVC, GCC, CLANG, Intel Compiler, and many other support it. Dunno why it is still not part of the standard, probably some member of the committee do not support it (maybe IBM XL C/C++ compier?)

It's not portable because even though the compilers support it, there is no guarantee that they all function the same between compilers. Header guards are guaranteed to function the same on every system thanks to the standard. They won't add it to the standard because the modules are supposed to guarantee what #pragma once alleges it will do.


The proposals now being experimented with so not replace header files, but
guarantee that a header is compiled once and minimize the inter-header
dependencies. Basically, headers become (just) interface specifications
and macros are mostly eliminated from them.

It's not portable because even though the compilers support it, there is no guarantee that they all function the same between compilers.

There's no guarentee of that basically anywhere in the C++ language, most of the standard is worded very vaguely and usually specifies only the minimum behavior that something has to do to be standards compliant. The only argument you even seem to be making here is that there isn't a standard definition of the basic things that pragma once must do(because it isn't a standard directive) even though it has shown to accomplish the same basic goal just fine across a variety of compilers.

In short you're basically saying we should avoid using it because it isn't standard, which is not a compelling reason IMO.

EDIT: Didn't read the whole topic before posting. Woops!

This topic is closed to new replies.

Advertisement