C-style unit -> C++ class, implementation function / structure issue

Discussion in 'C++' started by Jason Doucette, Jul 11, 2007.

  1. I am converting a C-style unit into a C++ class. I have an
    implementation function that was defined in the .cpp file (so it was
    hidden from the interface that exists in the .h file). It uses a
    structure that is only needed by the implementation, so it were
    declared in the .cpp file, as well.

    Now, when converting this into a class, the class definition exists in
    the .h file, since it's required by the interface. The implementation
    functions go under a "private" access specifier, so they are moved
    from the .cpp file into the .h file. But, it needs access to the
    above mentioned structure. It seems I must include the structure in
    the .h file, making it publicly accessible!

    Since no public member functions make use of the structure, I know
    that no one can do anything with it, so everything is ok. But it just
    seems UGLY to make something publicly accessible when it should be
    hidden in the implementation.

    Is there a way to achieve this?

    Jason
     
    Jason Doucette, Jul 11, 2007
    #1
    1. Advertising

  2. Re: C-style unit -> C++ class, implementation function / structureissue

    * Jason Doucette:
    > I am converting a C-style unit into a C++ class. I have an
    > implementation function that was defined in the .cpp file (so it was
    > hidden from the interface that exists in the .h file). It uses a
    > structure that is only needed by the implementation, so it were
    > declared in the .cpp file, as well.
    >
    > Now, when converting this into a class, the class definition exists in
    > the .h file, since it's required by the interface. The implementation
    > functions go under a "private" access specifier, so they are moved
    > from the .cpp file into the .h file. But, it needs access to the
    > above mentioned structure. It seems I must include the structure in
    > the .h file, making it publicly accessible!
    >
    > Since no public member functions make use of the structure, I know
    > that no one can do anything with it, so everything is ok. But it just
    > seems UGLY to make something publicly accessible when it should be
    > hidden in the implementation.
    >
    > Is there a way to achieve this?


    See PIMPL idiom. Generally it involves dynamic allocation. For hazards
    of avoiding dynamic allocation for PIMPL, see the relevant GOTW.

    However, it this is singleton you can do it like

    //---------------- .h file
    struct SomeSingleton
    {
    virtual formatMyDisks() = 0;
    static SomeSingleton& instance();
    };

    //---------------- .cpp file
    #include "the.h"
    namespace
    {
    struct Impl: SomeSingleton
    {
    virtual formatMyDisks() { /* Yes! */ }
    };
    }

    SomeSingleton& SomeSingleton::instance()
    {
    Impl theSingleton;
    return theSingleton;
    }

    Hth.,

    - Alf


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 11, 2007
    #2
    1. Advertising

  3. Jason Doucette

    Kai-Uwe Bux Guest

    Jason Doucette wrote:

    > I am converting a C-style unit into a C++ class. I have an
    > implementation function that was defined in the .cpp file (so it was
    > hidden from the interface that exists in the .h file). It uses a
    > structure that is only needed by the implementation, so it were
    > declared in the .cpp file, as well.
    >
    > Now, when converting this into a class, the class definition exists in
    > the .h file, since it's required by the interface. The implementation
    > functions go under a "private" access specifier, so they are moved
    > from the .cpp file into the .h file. But, it needs access to the
    > above mentioned structure. It seems I must include the structure in
    > the .h file, making it publicly accessible!
    >
    > Since no public member functions make use of the structure, I know
    > that no one can do anything with it, so everything is ok. But it just
    > seems UGLY to make something publicly accessible when it should be
    > hidden in the implementation.


    It appears that you are confusing header files and documentation. That
    information about class layout (including private members) is put into
    header files just goes to show that the intended reader of a header file is
    the compiler, not your fellow programmer.

    What is an implementation detail is not decided by whether it goes into a .h
    or into a .cpp file.


    > Is there a way to achieve this?


    For private, non-virtual member functions, you can turn them into global
    friend functions taking an additional pointer-to-class parameter. Every
    call would then explicitly have to pass the this-pointer. That is even more
    ugly.

    For private data-members, the compiler needs to know about them anyway for
    allocation purposes.

    I also have the vague recollection that the Pointer-to-Implementation idiom
    may provide a way around your problem.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jul 11, 2007
    #3
  4. > See PIMPL idiom. Generally it involves dynamic allocation.

    I found a pretty decent rundown of it here:
    http://www.gamedev.net/reference/articles/article1794.asp

    I see that it requires dynamic allocation, and an extra dereference
    for any of these functions. Since I am developing a performance
    application, this is unacceptable.


    > For hazards
    > of avoiding dynamic allocation for PIMPL, see the relevant GOTW.


    You mean http://www.gotw.ca/gotw/028.htm ?


    I guess, the real question is: Is there a more proper way than what I
    am already doing? I don't want to achieving the end result at any
    cost. If it's more complicated to do this than it would be if left as-
    is, then I'll leave it as-is. It's just a simple annoyance in C++,
    among many with interfaces/implementations <sigh>, but if C++ wants it
    to be this way, then I guess it should be this way. I won't try and
    fight for *any method possible* to get my implementation structures
    defined in the .cpp, if it requires great (or even moderate)
    complexity.

    I should have rephrased my question more accurately.

    Thanks for your reply,
    Jason
     
    Jason Doucette, Jul 11, 2007
    #4
  5. > It appears that you are confusing header files and documentation. That
    > information about class layout (including private members) is put into
    > header files just goes to show that the intended reader of a header file is
    > the compiler, not your fellow programmer.


    I am not confusing header files and documentation. Allow me to
    explain:

    I have a structure that only the implementation of the class uses.
    But, since C++ forces the entire class to be defined in the .h file,
    then all implementation functions must also be defined in the .h
    file. Files that #include the .h file can still only 'see' the
    interface, so that's fine. But, as a result, these implementation
    functions that use implementation-only structures force these
    structures to be defined in the .h file, making them visible to all
    files that #include the .h file.

    Ok, I just solved my issue by talking through it: I just have to make
    my structure itself defined within my class's private section... of
    course. I don't believe I've ever done that, so I didn't immediately
    think of it as a possibility.

    Thanks for your replies, they've been helpful.

    Jason
     
    Jason Doucette, Jul 12, 2007
    #5
  6. Jason Doucette

    James Kanze Guest

    On Jul 12, 1:18 am, Jason Doucette <> wrote:
    > > It appears that you are confusing header files and documentation. That
    > > information about class layout (including private members) is put into
    > > header files just goes to show that the intended reader of a header file is
    > > the compiler, not your fellow programmer.


    > I am not confusing header files and documentation. Allow me to
    > explain:


    > I have a structure that only the implementation of the class uses.
    > But, since C++ forces the entire class to be defined in the .h file,
    > then all implementation functions must also be defined in the .h
    > file. Files that #include the .h file can still only 'see' the
    > interface, so that's fine. But, as a result, these implementation
    > functions that use implementation-only structures force these
    > structures to be defined in the .h file, making them visible to all
    > files that #include the .h file.


    I'm not sure I understand. How did you get by in C without
    defining the struct in the header? You can wrap exactly the
    same technique in a class.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 12, 2007
    #6
  7. > I'm not sure I understand. How did you get by in C without
    > defining the struct in the header? You can wrap exactly the
    > same technique in a class.


    (I was using a C++ compiler, so my original code wasn't technically
    plain C code... I was using C++ without classes. I was using C-style
    units of functions, where the implementation existed all in the .cpp
    file, and the interface was visible in the .h file)

    I defined the struct in the .cpp file, since only the implementation
    functions in the .cpp file used it. The struct was not required for
    any interface functions, so it didn't have to exist in the .h file.

    My issue is that I didn't want to move the struct into the .h file
    when I converted this 'unit' into a C++ class. But, I now realize I
    can put the struct in the .h file, under the class's private section,
    and it'll be hidden from the interface. All is well.

    Thanks,

    Jason
     
    Jason Doucette, Jul 12, 2007
    #7
  8. Jason Doucette

    James Kanze Guest

    On Jul 12, 7:15 pm, Jason Doucette <> wrote:
    > > I'm not sure I understand. How did you get by in C without
    > > defining the struct in the header? You can wrap exactly the
    > > same technique in a class.


    > (I was using a C++ compiler, so my original code wasn't technically
    > plain C code... I was using C++ without classes. I was using C-style
    > units of functions, where the implementation existed all in the .cpp
    > file, and the interface was visible in the .h file)


    > I defined the struct in the .cpp file, since only the implementation
    > functions in the .cpp file used it. The struct was not required for
    > any interface functions, so it didn't have to exist in the .h file.


    In other words, the compilation firewall (pimpl) idiom. You can
    do exactly the same in C++.

    > My issue is that I didn't want to move the struct into the .h file
    > when I converted this 'unit' into a C++ class. But, I now realize I
    > can put the struct in the .h file, under the class's private section,
    > and it'll be hidden from the interface. All is well.


    Yes. C++ gives you the choice; C didn't.

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 12, 2007
    #8
  9. Re: C-style unit -> C++ class, implementation function / structureissue

    * James Kanze:
    > On Jul 12, 7:15 pm, Jason Doucette <> wrote:
    >>> I'm not sure I understand. How did you get by in C without
    >>> defining the struct in the header? You can wrap exactly the
    >>> same technique in a class.

    >
    >> (I was using a C++ compiler, so my original code wasn't technically
    >> plain C code... I was using C++ without classes. I was using C-style
    >> units of functions, where the implementation existed all in the .cpp
    >> file, and the interface was visible in the .h file)

    >
    >> I defined the struct in the .cpp file, since only the implementation
    >> functions in the .cpp file used it. The struct was not required for
    >> any interface functions, so it didn't have to exist in the .h file.

    >
    > In other words, the compilation firewall (pimpl) idiom. You can
    > do exactly the same in C++.


    Yes, I also suggested PIMPL, plus a special case (singleton) where no
    dynamic allocation is required.

    However, the OP is very very vague about his code, and PIMPL isn't
    necessarily required.

    For example,

    //------------------- the.h

    #ifdef THE_H
    #error On the usenet, we strive to minimize typing.
    #endif
    #define THE_H

    class SillyClass
    {
    private:
    struct Foo;
    void get( Foo& );
    public:
    void doThings();
    };


    //------------------- the.cpp

    #include "the.h"

    struct SillyClass::Foo
    {
    char data[100000];
    };

    void SillyClass::get( Foo& fooData ) { ... }

    void SillyClass::doThings()
    {
    Foo fooData;
    get( fooData );
    ...
    }

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 12, 2007
    #9
  10. > > (I was using a C++ compiler, so my original code wasn't technically
    > > plain C code... I was using C++ without classes. I was using C-style
    > > units of functions, where the implementation existed all in the .cpp
    > > file, and the interface was visible in the .h file)
    > > I defined the struct in the .cpp file, since only the implementation
    > > functions in the .cpp file used it. The struct was not required for
    > > any interface functions, so it didn't have to exist in the .h file.

    >
    > In other words, the compilation firewall (pimpl) idiom. You can
    > do exactly the same in C++.


    I didn't think my issue was the Pimpl Idiom... but I don't know
    exactly what Pimpl is about, so I could be wrong. I thought Pimpl was
    to allow the implementation to change without any visible effects in
    the interface, and thus saving compilation times.

    My issue is merely that I don't want an implementation-only structure
    visible at all. And this entire thread was rather unneeded, since C++
    does have a way to hide an implementation structure from being visible
    -- just define it in the class itself as private! I should have known
    this.


    > > My issue is that I didn't want to move the struct into the .h file
    > > when I converted this 'unit' into a C++ class. But, I now realize I
    > > can put the struct in the .h file, under the class's private section,
    > > and it'll be hidden from the interface. All is well.

    >
    > Yes. C++ gives you the choice; C didn't.


    Actually, in C, I had the structure declared in the .cpp file, so it
    wouldn't appear in the interface. I could change the .cpp file all I
    wanted, and since the .h file never changed, all was well.

    Only in C++ does the changes to the implementation all of a sudden
    require a recompile for any 'users' of the class, since they include
    the .h file which you are changing.

    Thanks for your thoughts,

    Jason
     
    Jason Doucette, Jul 12, 2007
    #10
  11. > However, the OP is very very vague about his code, and PIMPL isn't
    > necessarily required.


    I am sorry, it is no intention of mine to be vague. I was under the
    impression that I gave as many details as I could to explain my exact
    situation. Perhaps we're on two different pages. I am not sure if
    Pimpl applies to my concern. I merely was unaware that I could define
    structures inside of a class definition, and once I clued in that it
    was possible, it solved my concern. I had no issues about compilation
    times, etc.

    Jason
     
    Jason Doucette, Jul 12, 2007
    #11
  12. Jason Doucette

    James Kanze Guest

    On Jul 12, 10:27 pm, Jason Doucette <> wrote:
    > > > (I was using a C++ compiler, so my original code wasn't technically
    > > > plain C code... I was using C++ without classes. I was using C-style
    > > > units of functions, where the implementation existed all in the .cpp
    > > > file, and the interface was visible in the .h file)
    > > > I defined the struct in the .cpp file, since only the implementation
    > > > functions in the .cpp file used it. The struct was not required for
    > > > any interface functions, so it didn't have to exist in the .h file.


    > > In other words, the compilation firewall (pimpl) idiom. You can
    > > do exactly the same in C++.


    > I didn't think my issue was the Pimpl Idiom... but I don't know
    > exactly what Pimpl is about, so I could be wrong. I thought Pimpl was
    > to allow the implementation to change without any visible effects in
    > the interface, and thus saving compilation times.


    > My issue is merely that I don't want an implementation-only structure
    > visible at all. And this entire thread was rather unneeded, since C++
    > does have a way to hide an implementation structure from being visible
    > -- just define it in the class itself as private! I should have known
    > this.


    It wasn't clear, but I presumed that the C idiom you were
    talking about was to forward declare the struct in your header,
    to pass a pointer to it to all of the functions, and to only
    define it in the source files that used it. That's exactly what
    the compilation firewall idiom does in C++. In both C and C++,
    of course, it requires that the actual data be dynamically
    allocated (or static, if there is only one of them). If that's
    not the case, then I don't know what in C you are trying to map
    into C++.

    For the rest, of course, declaring member types (private or
    otherwise) is pretty much standard C++.

    > > > My issue is that I didn't want to move the struct into the .h file
    > > > when I converted this 'unit' into a C++ class. But, I now realize I
    > > > can put the struct in the .h file, under the class's private section,
    > > > and it'll be hidden from the interface. All is well.


    > > Yes. C++ gives you the choice; C didn't.


    > Actually, in C, I had the structure declared in the .cpp file, so it
    > wouldn't appear in the interface. I could change the .cpp file all I
    > wanted, and since the .h file never changed, all was well.


    In which case, you can do exactly the same in C++. (I tend to
    do it a lot, in fact.)

    > Only in C++ does the changes to the implementation all of a
    > sudden require a recompile for any 'users' of the class, since
    > they include the .h file which you are changing.


    Not if you do it the same way you do in C. As I said, in C++,
    you have the choice; both solutions work. Typically, declaring
    more in the header will result in slightly faster execution
    times, but more compiler dependencies. The smaller and simpler
    the class, the more the difference in execution times will be
    noticeable, and for something like complex, where the data
    structure is more or less predefined and won't ever change, but
    which is likely to be used in some tight loops, the C++ solution
    definitly has an advantage (and in fact, in C, you'd certainly
    declare the struct in header as well, even if it means that
    anyone can actually access the data directly). For larger, more
    complex objects, the time difference quickly becomes
    negligeable, however, and in large projects (say, from a million
    LOC up), the compilation firewall idiom is almost an automatism.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 13, 2007
    #12
  13. Jason Doucette

    James Kanze Guest

    On Jul 12, 9:14 pm, "Alf P. Steinbach" <> wrote:
    > * James Kanze:


    [...]
    > >> I defined the struct in the .cpp file, since only the implementation
    > >> functions in the .cpp file used it. The struct was not required for
    > >> any interface functions, so it didn't have to exist in the .h file.


    > > In other words, the compilation firewall (pimpl) idiom. You can
    > > do exactly the same in C++.


    > Yes, I also suggested PIMPL, plus a special case (singleton) where no
    > dynamic allocation is required.


    > However, the OP is very very vague about his code, and PIMPL isn't
    > necessarily required.


    Yes. I wasn't too sure myself what he meant. Two possibilities
    occured to me: one was that the struct was for some internal
    use, used in only within functions. But in that case, what's
    the problem. It seems obvious to me that you can do exactly the
    same thing in C++ as in C. A member function is certainly free
    to use non-member, locally defined types. (I regularly do this
    for classes which need to parse their data from strings, for
    example. The structures which support parsing are defined in an
    anonymous namespace in the source file, and aren't even named in
    the header.)

    The other possibility was the classical C idiom for
    "implementing" private data: in the header file, you forwarded
    declared the class (without defining it), and declared a number
    of functions, all of which took a pointer to the class as an
    argument. Only these functions, of course, need to know the
    definition of the class, since client code only manipulates a
    pointer. And I think you'll agree that this is really the same
    thing as the pimpl idiom, even if C programmers don't use that
    name, and it was widespread in C long before C++ became popular.
    (I was using it in the mid 1980's.)

    In the end, you have a choice:

    -- You can hide the data structure completely. Client code
    cannot possibly access it, because it doesn't even know the
    structure, and the structure can change without requiring
    recompilation of the client code. To do this, however,
    means that the actual data must be dynamically allocated
    (ignoring singletons and the like), and that there will
    often be an additional level of indirection. In C++, at
    least, deallocation can be handled automatically by means of
    the destructor; in C, it's up to the client code to
    explicitly call destruct.

    -- You can avoid the need for dynamic allocation, and allow the
    actual data to be on the (client) stack. In this case, the
    structure of the data must be known to the compiler of the
    client code, if only so that it knows how many bytes to
    allocate on the stack. Changing the data means recompiling
    the client code. And in C, this effectively means that all
    of the data are "public"; the client code has direct access
    to them. "Best practice" in C consists of defining a struct
    and a set of functions which manipulate it, and crossing
    your fingers that no client code manipulates it other than
    with your functions. At the very least, C++ means that you
    don't have to cross your fingers. (C++ also has a few other
    features, that are sometimes useful, but they're not that
    important; just icing on the cake, so to speak.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 13, 2007
    #13
  14. > It wasn't clear, but I presumed that the C idiom you were
    > talking about was to forward declare the struct in your header,
    > to pass a pointer to it to all of the functions, and to only
    > define it in the source files that used it.


    Oh right... because the structure is passed in as a pointer, the class
    definition doesn't need to know what the structure actually is. It
    just needs to be forward declared. And the definition can still exist
    in the .cpp file. I'll give that a shot. I knew you could do this
    with classes, and in fact I just did so recently, but I wasn't
    thinking that you could with structs, even though they are practically
    identical in C++, so I should have known.

    Now we're on the same page! :) Thanks...


    > That's exactly what
    > the compilation firewall idiom does in C++.


    Yes, because now I can change the implementation (structure and the
    functions that use it) without having to change the .h file. Right?


    > In both C and C++,
    > of course, it requires that the actual data be dynamically
    > allocated (or static, if there is only one of them).


    Not necessarily, the functions can deal with an address of a static
    instance of the structure. But, this is besides the point. I think
    you naturally assumed that any structure I was talking about would be
    passed in as a pointer, and of course, you were right.


    > > Actually, in C, I had the structure declared in the .cpp file, so it
    > > wouldn't appear in the interface. I could change the .cpp file all I
    > > wanted, and since the .h file never changed, all was well.

    >
    > In which case, you can do exactly the same in C++. (I tend to
    > do it a lot, in fact.)


    Right, and now I understand that you can. Without forward
    declaration, you cannot, and that's where I was stuck.


    > > Only in C++ does the changes to the implementation all of a
    > > sudden require a recompile for any 'users' of the class, since
    > > they include the .h file which you are changing.

    >
    > Not if you do it the same way you do in C. As I said, in C++,
    > you have the choice; both solutions work.


    Right.


    > Typically, declaring
    > more in the header will result in slightly faster execution
    > times, but more compiler dependencies.


    Fast execution times? Why is that?

    > The smaller and simpler
    > the class, the more the difference in execution times will be
    > noticeable, and for something like complex, where the data
    > structure is more or less predefined and won't ever change, but
    > which is likely to be used in some tight loops, the C++ solution
    > definitely has an advantage (and in fact, in C, you'd certainly
    > declare the struct in header as well, even if it means that
    > anyone can actually access the data directly).


    My data structures won't change often, and I'm writing a performance
    application, so I want speed where I can get it for free, for sure. I
    don't see how either method affects final execution times -- and if
    that's the case (the speed is the same in both cases), then my only
    concern is compilation times, which I would love to speed up.


    > For larger, more
    > complex objects, the time difference quickly becomes
    > negligible, however, and in large projects (say, from a million
    > LOC up), the compilation firewall idiom is almost an automatism.


    I can imagine. I am not there, but my LOC is high enough that
    compilation is a concern. One thing that would help is if both CPUs
    were used in the compile process; there's apps out there that'll do
    that, and I should take a look at some of them.

    Thanks for your help, James.

    Jason
     
    Jason Doucette, Jul 13, 2007
    #14
  15. > [snip] one was that the struct was for some internal
    > use, used in only within functions. But in that case, what's
    > the problem. It seems obvious to me that you can do exactly the
    > same thing in C++ as in C. A member function is certainly free
    > to use non-member, locally defined types.


    I thought the same, until I realized C++ forced me to declare my
    private member functions in the .h file, where as in C, I declared my
    implementation functions in the .cpp file. And this was ok, until
    those functions had to use this internal-use-only structure. But, as
    you've shown me, a forward declaration allows me to define the
    internal-use-only structure in the .cpp, but be referenced in the .h
    file in the private member function declarations. Problem solved!
    Tested and confirmed. :)

    > -- You can hide the data structure completely. Client code
    > cannot possibly access it, because it doesn't even know the
    > structure, and the structure can change without requiring
    > recompilation of the client code. To do this, however,
    > means that the actual data must be dynamically allocated
    > (ignoring singletons and the like), and that there will
    > often be an additional level of indirection. In C++, at
    > least, deallocation can be handled automatically by means of
    > the destructor; in C, it's up to the client code to
    > explicitly call destruct.


    Ah, now I get why you say dynamic allocation. You are speaking about
    a class data member. In my case, the implementation uses a structure,
    but it is only used internally in a few functions, so it is a function
    local variable. It is dynamically allocated, but it could be exist
    statically (although that wouldn't make sense if it were large, since
    it'd be on the stack, and that's a no-no).

    Jason
     
    Jason Doucette, Jul 13, 2007
    #15
  16. Jason Doucette

    BobR Guest

    Jason Doucette <> wrote in message...
    > > It wasn't clear, but I presumed that the C idiom you were
    > > talking about was to forward declare the struct in your header,
    > > to pass a pointer to it to all of the functions, and to only
    > > define it in the source files that used it.

    >
    > Oh right... because the structure is passed in as a pointer, the class
    > definition doesn't need to know what the structure actually is. It
    > just needs to be forward declared. And the definition can still exist
    > in the .cpp file. I'll give that a shot.


    "Cheshire cat" ( 'handle class' ).
    [ a 'loose' example. <G> ]

    // --- auto.h ---
    #include <ostream>

    class Car{ public:
    void initialize( size_t );
    void cleanup();
    void Print( std::eek:stream & );
    private:
    struct car; // the "Cheshire cat"
    car *theCar; // this is all the user sees
    };
    // --- auto.h --- END

    // --- auto.cpp --- // distribute as lib, .so, or ?
    #include "auto.h"

    struct engine{
    double weight;
    double cubic_capacity;
    };
    struct transmission{
    double weight;
    unsigned type;
    };

    struct Car::car{
    engine eng;
    transmission trans;
    size_t serial_no;
    car() : serial_no(0){
    eng.weight = 470.19;
    eng.cubic_capacity = 327;
    trans.weight = 105.7;
    trans.type = 2;
    }
    car( size_t serl ) : serial_no( serl ){
    // or, move all this to engine, transmission Ctors
    eng.weight = 470.19;
    eng.cubic_capacity = 327;
    trans.weight = 105.7;
    trans.type = 2;
    }
    };

    void Car::initialize( size_t Serial ){ // or in Car::Car() Ctor.
    theCar = new car( Serial );
    }

    void Car::cleanup(){ delete theCar; }
    // example. Better to do this in Car destructor so the user can't forget!

    void Car::print( std::eek:stream &out ){
    out<<"\ntheCar->serial_no="<<theCar->serial_no;
    out<<"\ntheCar->eng.weight="<<theCar->eng.weight;
    out<<"\ntheCar->eng.cubic_capacity="
    <<theCar->eng.cubic_capacity;
    out<<"\ntheCar->trans.weight="<<theCar->trans.weight;
    out<<"\ntheCar->trans.type="<<theCar->trans.type;
    out<<std::endl;
    return;
    }
    // --- auto.cpp --- END

    // --- main ---
    #include <iostream>
    #include "auto.h"

    int main(){
    Car myCar;
    myCar.initialize( 4032005 );
    myCar.Print( std::cout );
    myCar.cleanup();
    return 0;
    } // main()
    // --------------------------
    This is an old example I had laying around. Add constructors instead of
    using 'initialize()' (that's part of the 'loose', IMHO).

    Is that what you were/are doing?

    > I knew you could do this
    > with classes, and in fact I just did so recently, but I wasn't
    > thinking that you could with structs, even though they are practically
    > identical in C++, so I should have known.


    struct Base{ int number; virtual ~Base(){} };
    class Derived : public Base{ /* .... */ }; // no problem

    --
    Bob R
    POVrookie
     
    BobR, Jul 14, 2007
    #16
  17. Jason Doucette

    BobR Guest

    BobR wrote in message...
    >
    > "Cheshire cat" ( 'handle class' ).
    > [ a 'loose' example. <G> ]
    >
    > // --- auto.h ---


    Dang, meant to mention 'inclusion guards' here, but, I'll bet you know that.

    > #include <ostream>
    > class Car{ public:
    > };
    > // --- auto.h --- END


    --
    Bob R
    POVrookie
     
    BobR, Jul 14, 2007
    #17
  18. Jason Doucette

    James Kanze Guest

    On Jul 13, 8:16 pm, Jason Doucette <> wrote:

    [...]
    > > That's exactly what
    > > the compilation firewall idiom does in C++.


    > Yes, because now I can change the implementation (structure and the
    > functions that use it) without having to change the .h file. Right?


    Right. The idiom is far from new (although the name pimpl is
    fairly recent). In C, it was more often used as a means of
    making the structure private, rather than reducing compile
    times, although it does both.

    [...]
    > > Typically, declaring
    > > more in the header will result in slightly faster execution
    > > times, but more compiler dependencies.


    > Fast execution times? Why is that?


    The more the compiler knows, the better it can optimize. In
    this case, however, I was thinking more along the lines of being
    able to allocate the data directly on the stack, or in the
    class, rather than needing a dynamic allocation.

    If you want to see just how high the real cost can be, implement
    a trivial Complex class (e.g. "double real, imag ;"---no need
    for the operators for this test), then reimplement it using the
    compilation firewall idiom (
    class Complex
    {
    class Impl ;
    Impl * myImp ;
    public:
    // ...
    } ;
    ).
    Now create an std::vector of a couple of million of each:).

    Of course, this is an extreme example, but you get the idea.

    > > The smaller and simpler
    > > the class, the more the difference in execution times will be
    > > noticeable, and for something like complex, where the data
    > > structure is more or less predefined and won't ever change, but
    > > which is likely to be used in some tight loops, the C++ solution
    > > definitely has an advantage (and in fact, in C, you'd certainly
    > > declare the struct in header as well, even if it means that
    > > anyone can actually access the data directly).


    > My data structures won't change often, and I'm writing a performance
    > application, so I want speed where I can get it for free, for sure.


    The question is what the difference is, and when. Using the
    compilation firewall idiom requires an allocation in the
    constructor, a delete in the destructor, and (generally) an
    extra indirection in every function call. If the object
    lifetimes are long, and the functions are complex, the
    difference isn't measurable. If objects are frequently created
    and destroyed (value semantics with deep copy, for example), and
    the functions are almost trivial (complex::eek:perator+), the
    difference can be important.

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 14, 2007
    #18
  19. Jason Doucette

    James Kanze Guest

    On Jul 14, 3:31 am, "BobR" <> wrote:

    [...]
    > "Cheshire cat" ( 'handle class' ).


    That was my favorite name for it too:). All you see is the
    smile of the class. (Even though the technique goes back to
    long before the name was invented.)

    --
    James Kanze (Gabi Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 14, 2007
    #19
  20. Jason Doucette

    BobR Guest

    James Kanze wrote in message...
    On Jul 14, 3:31 am, "BobR" wrote:
    > [...]
    > > "Cheshire cat" ( 'handle class' ).

    >
    > That was my favorite name for it too:). All you see is the
    > smile of the class. (Even though the technique goes back to
    > long before the name was invented.)


    I should have mentioned my source. I modified Bruce Eckel's example for a
    poster a couple years back. Bruce's footnote (for "Cheshire cat") in "TiCpp,
    v1" says:

    "[37] This name is attributed to John Carolan, one of the early pioneers in
    C++, and of course, Lewis Carroll. This technique can also be seen as a form
    of the "bridge" design pattern, described in Volume 2.
    "

    It's a handy little 'almost pattern' when someone wants to hide code from an
    end user (like in a lib or *.so (<yech>DLL)).

    I tried to use KISS (in what I posted) because member initialization(s)
    depends on how/where control is needed.

    --
    Bob R
    POVrookie
     
    BobR, Jul 14, 2007
    #20
    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.
Similar Threads
  1. dlo_olb
    Replies:
    2
    Views:
    2,350
    Fredrik Lundh
    Jun 25, 2003
  2. Edvard Majakari
    Replies:
    4
    Views:
    701
    Edvard Majakari
    Feb 25, 2005
  3. VvanN
    Replies:
    5
    Views:
    510
    Phlip
    Apr 28, 2006
  4. Ken Varn
    Replies:
    0
    Views:
    506
    Ken Varn
    Apr 26, 2004
  5. Jayden
    Replies:
    9
    Views:
    309
    alex23
    Sep 27, 2012
Loading...

Share This Page