Re: Splitting up the definitions of a class into different files (splitting public from private)?

Discussion in 'C++' started by John Dibling, Jul 19, 2003.

  1. John Dibling

    John Dibling Guest

    On Sat, 19 Jul 2003 15:32:10 GMT, "Mark" <>
    wrote:

    >Is it possible in C++ to somehow split the public and private class member definitions of a class such that the "public" .h file has just the public definitions?


    Can't be done. A datatype must be completely defined in one
    translation unit. In fact, in one block. However, you do have
    options...

    One possibility is to define an interface ABC class with only the
    public methods defined, and derive a concrete class from the ABC with
    your private goodies. You could hide the goodies class from public
    consumption in a number of different ways, including declaring and
    implementing it all in one CPP file. One thing to note with using
    this method is that it requires you to implement some sort of static
    factory method the clients can use to instantiate your object.

    Here are 3 source files which demonstrate this. You should be able to
    compile these without modification & run them. They were built under
    MSVC, but it should be platform-independant...

    <FILE: interface.h>
    #ifndef IFC_H
    #define IFC_H

    enum DOGTYPE
    {
    dtEskimo,
    dtSheppard
    };

    class IDog
    {
    public:
    static IDog* CreateDog(DOGTYPE); // factory

    virtual bool Bark() = 0;
    virtual bool Sleep() = 0;
    };


    #endif // IFC_H
    </FILE: interface.h>

    <FILE:classes.h>
    #include <cstdlib>
    #include <cassert>
    #include <iostream>
    #include "interface.h"

    using namespace std;

    // Declarations //
    class Eskimo : public IDog
    {
    public:
    bool Bark() { DoEskimoBark(); return true; }
    bool Sleep() { DoEskimoSleep(); return true; }
    protected:
    void DoEskimoBark() { cout << "Yip, Yip!" << endl; return;};
    void DoEskimoSleep() { cout << "zzz!" << endl; return; }
    };

    class Sheppard : public IDog
    {
    public:
    bool Bark() { DoSheppardBark(); return true; }
    bool Sleep() { DoSheppardSleep(); return true; }
    protected:
    void DoSheppardBark() { cout << "WOOF, WOOF!" << endl;
    return;};
    void DoSheppardSleep() { cout << "zzz zzz zzz zzz!" << endl;
    return; }
    };

    // Factory method ///
    IDog*
    IDog::CreateDog(DOGTYPE dt)
    {
    // prologue
    IDog* pRet = 0;
    // instantiate dog object
    switch(dt)
    {
    case dtEskimo :
    pRet = new Eskimo;
    break;
    case dtSheppard :
    pRet = new Sheppard;
    break;
    default :
    // ERROR STATE - Invalid object type specified //
    assert(false);
    break;
    }
    // epilogue
    return pRet;
    }
    </FILE: classes.h>

    <FILE: main.cpp>
    #include <cstdlib>
    #include <vector>
    using namespace std;

    #include "interface.h"

    typedef std::vector<IDog*> DOGS;

    int main()
    {
    // prologue
    DOGS vDogs;
    DOGS::iterator itDog; // get around stoopid MSVC bug
    // instantiate dogs
    IDog* pEskie = IDog::CreateDog(dtEskimo);
    IDog* pSheppard = IDog::CreateDog(dtSheppard);
    vDogs.push_back(pEskie);
    vDogs.push_back(pSheppard);
    // bark the doggies
    for( itDog = vDogs.begin(); vDogs.end() != itDog; ++itDog )
    {
    // prologue
    IDog* piDog = *itDog;
    // bark the dog
    piDog->Bark();
    // epilogue
    }
    // sleep the doggies
    for( itDog = vDogs.begin(); vDogs.end() != itDog; ++itDog )
    {
    // prologue
    IDog* piDog = *itDog;
    // bark the dog
    piDog->Sleep();
    // epilogue
    }
    // epilogue
    for( itDog = vDogs.begin(); vDogs.end() != itDog; ++itDog )
    {
    // prologue
    IDog* piDog = *itDog;
    // release resources
    delete piDog;
    // epilogue
    }
    vDogs.clear();
    return 0;
    }
    </FILE: main.cpp>

    </dib>

    Share and Enjoy

    John Dibling
    email: dib@substitute_my_full_last_name_here.com
    Witty banter omitted for your protection
     
    John Dibling, Jul 19, 2003
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page