简体   繁体   中英

Separating Interface and Implementation in C++

If I have a simple header file:

namespace aNamespace {
    class AClass {
        public:
        AClass();
        ~AClass();

        bool Init();
        void Shutdown();
    };
}

What is the 'correct' way to implement this class in the corresponding CPP file? I can see two options:

Option A

namespace aNamespace {
    class AClass {
        public:
        AClass() { ... }
        ~AClass() { ... }

        bool Init() { ... }
        void Shutdown() { ... }
    };
}

Option B

namespace aNamespace {
    AClass::AClass() { ... }
    AClass::~AClass() { ... }

    bool AClass::Init() { ... }
    void AClass::Shutdown() { ... }
}

The problem I see with Option B is that it's hard to add implementation-specific members to AClass - eg what if the implementation requires a std::wstring or so as a storage variable; but that variable isn't defined in the header file?

The reason I'm asking this is because I may wish to have multiple implementations of AClass , and select which one to link according to some external variable (eg the target platform or architecture).

Another option would be to actually make name of each implementation platform specific and have a simple typedef switch in header to control which one is chosen based on target/architecture:

#ifdef target1
typedef AClass Target1ClassImplementation;
#elif  defined target2
typedef AClass Target2ClassImplementation;
#else
#error AClass is not implemented for current target
#endif

If desired, common interface can be encapsulated in a base class implementations derive from. It is less error prone since is more explicit in sense which implementation is for what target, while allows using AClass regardlesss of a platform target outside of header.

B is much better in most cases:

Advantages:

  • Hide implementation details.
  • Less #includes in header files (less exposed dependencies!):
    • Faster builds
    • 2 classes can call each other's functions. Very tricky to do if both are in headers.
    • Changes to implementation do affect other classes (build time).

Disadvantages: - Functions in CPP file do not inline in other modules (across library boundaries)

Optimal: Decide per function which is best. Short one liners to the header and longer ones to the cpp(s). You can have more than 1 source file for the class implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM