2013-03-07 106 views
3

我有一个C++类声明了一个单一的静态成员。整个类都包含在一个头文件中,我宁愿避免创建一个.cpp文件来简单地包含静态成员定义。我一直试图使用静态关键字(在C的意义上)和匿名命名空间,这两个应该给头文件静态链接(asfaik)声明的变量,但都没有办法工作,任何人都可以给我一个解决方案问题?声明的静态成员与静态链接

struct ServiceType {} ; 
struct Transport 
{ 
    static ServiceType service ; 
}; 

//error: definition of ‘Transport::service’ is not in namespace enclosing ‘Transport’ 
//namespace { ServiceType Transport::service ; } 

//error: ‘static’ may not be used when defining a static data member 
//static ServiceType Transport::service ; 
+0

'static'值不一定意味着静态链接。它恰好是相同的关键字,但其含义完全不同。你不能有静态链接的成员。所以你想要的是不可能的。你*有*在某处定义符号。没有办法绕过它。 – 2013-03-07 13:16:21

+0

我理解静态关键字的多种用法之间的区别 – 2013-03-07 13:32:24

回答

4

有它,如果你坚持链接错误,如果目标只是不必创建一个.cpp文件时, 简单的解决办法可能是包装静态数据 成员在一个内联静态成员函数中。换句话说, 是这样的:

struct Transport 
{ 
    static ServiceType& service() 
    { 
     static ServiceType theData; 
     return theData; 
    } 
}; 

当然,你必须使用语法service(),而 不仅仅是service,访问它。当应用于成员

+0

这很好,谢谢。 – 2013-03-07 15:07:03

0

匿名命名空间在整个编译单元中可见。如果您将标头包含在多个源文件中,则最终会有多个名为Transport :: service的符号。这是行不通的,因为你会从链接器得到一个symbol already defined错误。

恐怕C++的工作方式不允许您在不移动.cpp文件中service符号的定义的情况下摆脱此问题。

所以,在.cpp文件,无论是做Transport::ServiceType service;,或者如果你不想service是一个命名空间的一部分在.cpp页眉和ServiceType service;extern ServiceType service;

1

不能定义具有内部链接的静态成员。

如果定义在头文件中的静态成员service,你将不得不在每一个源,在这里你有这个头文件的实例。如果这不是一个问题,可以环绕整个struct Transport

namespace { 
struct Transport 
{ 
    static ServiceType service ; 
}; 

ServiceType Transport::service; 
} 
+0

您的意思是静态生命周期,而不是静态链接。 (没有静态链接这样的东西。) – 2013-03-07 14:01:41

+0

使用匿名命名空间不会起作用。他将在每个包含他的头文件的翻译单元中完成一个完全不同的类(和静态实例)。 – 2013-03-07 14:02:52

+0

@JamesKanze不,我的意思是联系而不是生命。尽管如此,重写为标准术语。 – 2013-03-07 14:27:47

0

一个匿名的命名空间尝试

ServiceType Transport::service ; 

这是错误的:

namespace { ServiceType Transport::service ; } //You are adding it in an unnamed namespace, rather than whatever namespace Transport is actually in - presumably the global namespace 

这是错误的:

static ServiceType Transport::service ; // You dont need the static here, only in the struct. 

我希望你会得到在头虽然