static member linker problem

Discussion in 'C++' started by Philipp Kraus, Oct 11, 2011.

  1. Hello,

    I have written a header-only class with inline calls like in a header
    file only like:

    --header.hpp---
    class myclass {

    public :

    private :
    static anotherclass obj;
    }

    No i do the initialization in the same header file:
    anotherclass myclass::eek:bj;

    If I include this header in one cpp of another project, everything
    works fine, but if the projects has more than one cpp
    file, that includes the header, I get the linker error, that there are
    duplicated calls for the myclass::eek:bj part.
    I can create a cpp file with the initialization, but is there a
    "header-only" solution to do the initialization without
    linker problems eg a design pattern or anything else? My goal the
    static members should be initialize within
    their header file and the header files can be include more than once.

    Thanks

    Phil
     
    Philipp Kraus, Oct 11, 2011
    #1
    1. Advertising

  2. Philipp Kraus <> wrote:
    > I can create a cpp file with the initialization, but is there a
    > "header-only" solution to do the initialization without
    > linker problems eg a design pattern or anything else?


    C++ does not support instantiating static members "inline" in the same
    way as function definitions, except for templates (where the "inlineness"
    is implicit).

    Either you have to use a compilation unit for the static member, or
    you have to make the class templated.
     
    Juha Nieminen, Oct 11, 2011
    #2
    1. Advertising

  3. On 2011-10-11 14:58:24 +0200, Juha Nieminen said:

    > Philipp Kraus <> wrote:
    >> I can create a cpp file with the initialization, but is there a
    >> "header-only" solution to do the initialization without
    >> linker problems eg a design pattern or anything else?

    >
    > C++ does not support instantiating static members "inline" in the same
    > way as function definitions, except for templates (where the "inlineness"
    > is implicit).
    >
    > Either you have to use a compilation unit for the static member, or
    > you have to make the class templated.


    I think a own compilation unit is the best way, because there are only
    two classes
    with static members, that are not templated

    Thanks

    Phil
     
    Philipp Kraus, Oct 11, 2011
    #3
  4. On 10/11/2011 8:53 AM, Philipp Kraus wrote:
    > I have written a header-only class with inline calls like in a header
    > file only like:
    >
    > --header.hpp---
    > class myclass {
    >
    > public :
    >
    > private :
    > static anotherclass obj;
    > }
    >
    > No i do the initialization in the same header file:
    > anotherclass myclass::eek:bj;


    It's known in some places as a "definition".

    > If I include this header in one cpp of another project, everything works
    > fine, but if the projects has more than one cpp
    > file, that includes the header, I get the linker error, that there are
    > duplicated calls for the myclass::eek:bj part.


    Headers are inconsequential, they are not compiled. Translation units
    are compiled. If you have your *definition* in more than one
    translation unit (by means of including the same definition code in more
    than one translation unit), you have what is known as "multiple
    definition" of that symbol (object), and that's prohibited in C++.

    > I can create a cpp file with the initialization, but is there a
    > "header-only" solution to do the initialization without
    > linker problems eg a design pattern or anything else?


    Yes: don't include it in more than one translation unit.

    > My goal the static
    > members should be initialize within
    > their header file and the header files can be include more than once.


    That's not achievable in C++.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 11, 2011
    #4
  5. On 11.10.2011 15:45, Victor Bazarov wrote:
    > On 10/11/2011 8:53 AM, Philipp Kraus wrote:
    >> I have written a header-only class with inline calls like in a header
    >> file only like:
    >>
    >> --header.hpp---
    >> class myclass {
    >>
    >> public :
    >>
    >> private :
    >> static anotherclass obj;
    >> }
    >>

    [snippety!]

    > > My goal the static
    >> members should be initialize within
    >> their header file and the header files can be include more than once.

    >
    > That's not achievable in C++.


    Oh, it's easy.

    E.g.

    template< class Dummy_ >
    struct myclass_statics
    {
    static anotherclass obj;
    };

    template< class Dummy_ >
    anotherclass myclass_statics<Dummy_>::eek:bj;


    class myclass
    : private myclass_statics<void>
    {
    public:
    // blah blah
    };

    It's just very verbose, since C++ doesn't have a clean "inline" keyword.


    Cheers & hth.,

    - Alf
     
    Alf P. Steinbach, Oct 11, 2011
    #5
  6. On 11.10.2011 14:53, Philipp Kraus wrote:
    > Hello,
    >
    > I have written a header-only class with inline calls like in a header
    > file only like:
    >
    > --header.hpp---
    > class myclass {
    >
    > public :
    >
    > private :
    > static anotherclass obj;
    > };


    Instead do like

    class myclass
    {
    public:
    // whaver
    private:
    static anotherclass& obj()
    {
    static anotherclass theObj;
    return theObj;
    }
    };

    Cheers & hth.,

    - Alf
     
    Alf P. Steinbach, Oct 11, 2011
    #6
  7. On 10/11/2011 11:26 AM, Alf P. Steinbach wrote:
    > On 11.10.2011 14:53, Philipp Kraus wrote:
    >> Hello,
    >>
    >> I have written a header-only class with inline calls like in a header
    >> file only like:
    >>
    >> --header.hpp---
    >> class myclass {
    >>
    >> public :
    >>
    >> private :
    >> static anotherclass obj;
    >> };

    >
    > Instead do like
    >
    > class myclass
    > {
    > public:
    > // whaver
    > private:
    > static anotherclass& obj()
    > {
    > static anotherclass theObj;
    > return theObj;
    > }
    > };
    >


    That will introduce "extraneous" parentheses after the name of the
    "object" (although it is only used in the class itself, so it's not such
    a big deal, of course). The template solution (that you have posted in
    response to my "no possible" claim) is a neat trick, but requires a
    template definition for every class with a static obj. It can be
    wrapped in a bunch of macros, and made "cleaner" and "less verbose" (so
    to speak), OTOH, why verbosity never scared the existing compilers,
    right? Most of the C++ Standard Library is very verbose...

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 11, 2011
    #7
    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. adeht
    Replies:
    1
    Views:
    378
    lilburne
    Feb 2, 2004
  2. Karl Heinz Buchegger

    gcc linker won't handle class member

    Karl Heinz Buchegger, Aug 30, 2004, in forum: C++
    Replies:
    3
    Views:
    345
    Sigmund Skjelnes
    Aug 30, 2004
  3. Serge
    Replies:
    4
    Views:
    8,722
    Paavo Helde
    Dec 19, 2004
  4. Replies:
    2
    Views:
    304
    Victor Bazarov
    Aug 9, 2006
  5. dolphin
    Replies:
    3
    Views:
    1,362
    Pete Becker
    Dec 5, 2007
Loading...

Share This Page