使用静态链接声明静态成员

时间:2013-03-07 13:05:30

标签: c++ static namespaces linkage

我有一个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 ;

4 个答案:

答案 0 :(得分:5)

如果目标只是不必创建.cpp文件,那么 最简单的解决方案可能是包装静态数据 内联静态成员函数中的成员。换一种说法, 类似的东西:

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

当然,您必须使用语法service() 而不仅仅是service,才能访问它。

答案 1 :(得分:1)

您无法定义具有内部链接的静态成员。

如果在头文件中定义静态成员service,则每个源中都有一个实例,其中包含此头文件。如果这不是问题,您可以围绕整个struct Transport

包装一个匿名命名空间
namespace {
struct Transport
{
    static ServiceType service ;
};

ServiceType Transport::service;
}

答案 2 :(得分:0)

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

我担心C ++的工作方式不允许你在不移动service文件中.cpp符号的定义的情况下侥幸逃脱。

因此,在.cpp文件中,执行Transport::ServiceType service;或者如果您不希望service成为命名空间的一部分,请在标题中extern ServiceType service; { {1}}中的{1}}。

答案 3 :(得分: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.

如果您坚持在标题中使用

,我希望您会收到链接器错误