Advertisement

Proper C++ header file?

Started by November 14, 2014 11:47 PM
25 comments, last by Clobslee 10 years, 2 months ago

For a proper header file you should not include a bunch of files you do not need. Only add them if you cant forward declare a class and prefer having the include in the cpp file, but minimize these, too.

And use descriptive names where you dont need to guess if, for example, loc is location (cant be, a string location is weird?), lines of code(uhh no, why?) or something else.

It would be good to learn about how to use const references and the constructor initializer list, to see how these prevent useless copying.

Try following the "tell, dont ask" principle and only add get/set methods if you cant replace them by methods that do the real work inside the class. The remaining one-line-methods could then be put into the header so they can be inlined.

Not sure how I just saw this but thanks a bunch! I haven't got to anything const related in class yet (which seems a bit odd). I'll open the bible and read a bit.

Cheers!

Some general thoughts and ramblings.

Ramblings are inlined in comments. :).


#ifndef INCLUDED_TILEMAP_H
#define INCLUDED_TILEMAP_H

// You are only using string.
// You should only include string.
// Judiciously including only what you use will improve compile times.
// This is so important that people have written tools to ensure that a
// code base adheres to this:
// https://code.google.com/p/include-what-you-use/wiki/WhyIWYU
//
#include <string>

// Style guides, totally worth reading up on.
// Seeing as you are just starting out, choose a different one for every project.
// Adhere to it. Learn what you don't like about it:
// http://google-styleguide.googlecode.com/svn/trunk/cppguide.html
// http://udn.epicgames.com/Three/CodingStandard.html
// http://wiki.ros.org/CppStyleGuide
// Many more by googling "c++ style guide" + some company name.
class TileMap
{
  public:
    // Declare the default constructor. Even though a default is provided, it is
    // a really, really good habit to get into.
    //
    TileMap();

    // Declare the copy constructor. It will save you later.
    // I would also (maybe) suggest looking into the concept of "non copyable".
    // 
    TileMap(const TileMap& from);
    TileMap(const std::string& name, const std::string& location);

    // Declare the default destructor. Even though a default is provided, it is a 
    // life saving habit to get into.
    //
    ~TileMap();

    // Again, one is provided, but quite honestly, this is a another life saving habit
    // to get into when you are just starting out.
    //
    TileMap&            operator=(const TileMap &);

    // Const references for input when setting a value.
    //
    void                setName(const std::string& inName);

    // I assume that "loc" is location. 
    // A longer variable name will help you later when you have other stuff to think about.
    //
    void                setLocation(const std::string& inLocation);

    // Accessors usually are const. I tend to loathe using get on the "gettor".
    // Returning a const ref here is also faster. 
    // I also suggest reading up on return value optimization...
    // http://en.wikipedia.org/wiki/Return_value_optimization
    // 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 :) ).
    // http://en.wikipedia.org/wiki/Copy-on-write 
    // Now I'm rambling, so I will stop.
    //
    const std::string&  name() const;
    const std::string&  location() const;

  private:
    // You should probably consider marking your members with a character 
    // that indicates the variable is a member. 
    // Some naming models become very elaborate at the expense of readability.
    // I prefer underscores, others prefer m, some specs prefer extended information
    // for pointers. I.e., if _name were a pointer, the variable would be _pName or mpName.
    //
    std::string         _name; // or mName
    std::string         _loc; // or mLoc
};


#endif

Advertisement

I would also suggest to replace

#ifndef INCLUDED_TILEMAP_H

#define INCLUDED_TILEMAP_H

by

#pragma once

it's simpler and you don't need the #endif at the end :)

I would also suggest to replace

#ifndef INCLUDED_TILEMAP_H

#define INCLUDED_TILEMAP_H

by

#pragma once

it's simpler and you don't need the #endif at the end smile.png

The only problem with it is that it is not part of the C/C++ standard, so while it is supported by major compilers, it can't be guaranteed to always work.

I was fixing to ask, isn't #pragma once compiler vendor implementation so there is no guarantee they are implemented the same or function the same?

I would also suggest to replace

#ifndef INCLUDED_TILEMAP_H

#define INCLUDED_TILEMAP_H

by

#pragma once

it's simpler and you don't need the #endif at the end smile.png

The only problem with it is that it is not part of the C/C++ standard, so while it is supported by major compilers, it can't be guaranteed to always work.

I thought that I should extend this a little.

Compiler support for this is wide.

http://en.wikipedia.org/wiki/Pragma_once

However, I'm yet to see someone screw up #ifndef INCLUDED_#

(Aside from me, just then). tongue.png.

Maybe I'm just being old and crotchety and indicating to people to get off of my lawn.

For me, I prefer #ifndef/#define.

I prefer not to see "#pragma" in my code unless it is inline adding a library (which I prefer it wouldn't (still guilty of this myslef)), or disabling particularly annoying Microsoft compile warnings.

I started with Visual Studio 5.0, and #pragma meant "hear be dragons" to me.

I think that preference on this may fit under "religious/other".

smile.png.

Advertisement

I've seen people screw it up at least three times in a single project, because new files were always copy/pasted from existing files (nobody wants to worry about copyright notices, doxygen syntax, etc.). Guess what got copied without updating: doxygen info (file name, file description), copyright header and... bingo... the include guards.

Then there's people not able to consistently follow a naming scheme for the guards or insisting on starting them with _ or __ (triggering plenty of complaints in code analysis tools).

Unless you need to support some very exotic or outdated compilers, #pragma once is easier, safer and allegedly faster in some implementations.

f@dzhttp://festini.device-zero.de

I would also suggest to replace

#ifndef INCLUDED_TILEMAP_H

#define INCLUDED_TILEMAP_H

by

#pragma once

it's simpler and you don't need the #endif at the end smile.png

The only problem with it is that it is not part of the C/C++ standard, so while it is supported by major compilers, it can't be guaranteed to always work.

Which is not a problem, just a thing to keep in mind. In fact pragma once is supported by every compiler that you would know the name of off the top of your head.

Frankly I don't see a reason not to use it unless someone specifically asks you not to, like at a job or something. Wasted opportunity to give more information to the preprocessor.


Frankly I don't see a reason not to use it unless someone specifically asks you not to, like at a job or something. Wasted opportunity to give more information to the preprocessor.

The reason I brought it up was because we're in the "For Beginners" section, where we try to be as exact and correct as possible. There are also a lot of students reading this section, and students are often instructed to follow standards. For them, using non-standard pragmas could cost marks.

The reason I brought it up was because we're in the "For Beginners" section, where we try to be as exact and correct as possible.

Which we are, the only thing I agree with so far is that yes, it is non-standard, it isn't specified in the standard.

There are also a lot of students reading this section, and students are often instructed to follow standards.

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.

If we want to talk about common, pragma once is probably one of the most common non-standardized preprocessor directives.

For them, using non-standard pragmas could cost marks.

Or it might not, depends on the teacher, which is why they are being taught right now that pragma once is a useful tool and you should prefer to use it if you can, not to always default to #ifndef header guards because they might be more pragmatically correct to a teacher. Not everyone here is a student.

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."

This topic is closed to new replies.

Advertisement