Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   static member linker problem (http://www.velocityreviews.com/forums/t754759-static-member-linker-problem.html)

Philipp Kraus 10-11-2011 12:53 PM

static member linker problem
 
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::obj;

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::obj 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



Juha Nieminen 10-11-2011 12:58 PM

Re: static member linker problem
 
Philipp Kraus <philipp.kraus@flashpixx.de> 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.

Philipp Kraus 10-11-2011 01:10 PM

Re: static member linker problem
 
On 2011-10-11 14:58:24 +0200, Juha Nieminen said:

> Philipp Kraus <philipp.kraus@flashpixx.de> 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


Victor Bazarov 10-11-2011 01:45 PM

Re: static member linker problem
 
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::obj;


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::obj 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

Alf P. Steinbach 10-11-2011 03:24 PM

Re: static member linker problem
 
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_>::obj;


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 10-11-2011 03:26 PM

Re: static member linker problem
 
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

Victor Bazarov 10-11-2011 04:17 PM

Re: static member linker problem
 
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


All times are GMT. The time now is 05:06 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.