static member linker problem

P

Philipp Kraus

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
 
J

Juha Nieminen

Philipp Kraus said:
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.
 
P

Philipp Kraus

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
 
V

Victor Bazarov

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
 
A

Alf P. Steinbach

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
 
A

Alf P. Steinbach

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
 
V

Victor Bazarov

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top