当前位置:  开发笔记 > 编程语言 > 正文

对静态类成员的未定义引用

如何解决《对静态类成员的未定义引用》经验,为你挑选了4个好方法。

谁能解释为什么以下代码无法编译?至少在g ++ 4.2.4上.

更有趣的是,为什么它会在我将MEMBER转换为int时进行编译?

#include 

class Foo {  
public:  
    static const int MEMBER = 1;  
};

int main(){  
    vector v;  
    v.push_back( Foo::MEMBER );       // undefined reference to `Foo::MEMBER'
    v.push_back( (int) Foo::MEMBER ); // OK  
    return 0;
}

Drew Hall.. 193

您需要在某处(在类定义之后)实际定义静态成员.试试这个:

class Foo { /* ... */ };

const int Foo::MEMBER;

int main() { /* ... */ }

那应该摆脱未定义的引用.



1> Drew Hall..:

您需要在某处(在类定义之后)实际定义静态成员.试试这个:

class Foo { /* ... */ };

const int Foo::MEMBER;

int main() { /* ... */ }

那应该摆脱未定义的引用.


我花了很多时间搞清楚如果类定义在头文件中,那么静态变量的分配应该在实现文件中,而不是标题.
这个答案只涉及问题的第一部分.第二部分更有趣:为什么添加NOP强制转换使其无需外部声明就可以工作?
好点,内联静态const整数初始化创建一个范围整数常量,你不能取地址,vector会引用一个引用参数.

2> Douglas Mayl..:

问题来自于新C++功能的有趣冲突以及您正在尝试做的事情.首先,我们来看看push_back签名:

void push_back(const T&)

它期望引用类型的对象T.在旧的初始化系统下,存在这样的成员.例如,以下代码编译得很好:

#include 

class Foo {
public:
    static const int MEMBER;
};

const int Foo::MEMBER = 1; 

int main(){
    std::vector v;
    v.push_back( Foo::MEMBER );       // undefined reference to `Foo::MEMBER'
    v.push_back( (int) Foo::MEMBER ); // OK  
    return 0;
}

这是因为某个实际对象的某个值存储在其中.但是,如果切换到指定静态const成员的新方法(如上所述),Foo::MEMBER则不再是对象.这是一个常数,有点类似于:

#define MEMBER 1

但是没有预处理器宏(并且具有类型安全性)的头痛.这意味着期望参考的向量不能得到一个.


-1:这根本不是真的.当你在某处使用_odr-used_时,你仍然应该定义内联初始化的静态成员.编译器优化可能会消除您的链接器错误不会改变它.在这种情况下,你的左值到右值的转换(感谢`(int)`强制转换)发生在翻译单元中,具有完美的常量可见性,并且`Foo :: MEMBER`不再是_odr-used_.这与第一个函数调用形成对比,在第一个函数调用中传递引用并在其他地方进行求值.
谢谢,这有所帮助...如果尚不存在,则可能符合http://stackoverflow.com/questions/1995113/strangest-language-feature ...

3> Richard Cord..:

如果以某种方式需要定义,则C++标准需要静态const成员的定义.

该定义是必需的,例如,如果使用它的地址. push_back通过const引用获取其参数,因此编译器需要您的成员的地址,您需要在命名空间中定义它.

当您显式地转换常量时,您正在创建一个临时的,这是临时的,它绑定到引用(在标准中的特殊规则下).

这是一个非常有趣的案例,我实际上认为值得提出一个问题,以便将std更改为对您的常量成员具有相同的行为!

虽然,以一种奇怪的方式,这可以被视为合法使用一元'+'运算符.基本上,结果unary +是rvalue,因此rvalues绑定到const引用的规则适用,我们不使用静态const成员的地址:

v.push_back( +Foo::MEMBER );


+1.是的,对于类型为T的对象x,表达式"(T)x"可用于绑定const ref,而普通的"x"则不能.我喜欢你关于"一元+"的观察!谁会想到可怜的小"一元+"实际上有用...... :)
考虑一般情况......在C++中是否有任何其他类型的对象具有以下属性:只有在已经定义的情况下它才能被用作左值但是(2)可以被转换为右值而不是界定?

4> 小智..:

Aaa.h

class Aaa {

protected:

    static Aaa *defaultAaa;

};

Aaa.cpp

// You must define an actual variable in your program for the static members of the classes

static Aaa *Aaa::defaultAaa;

推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有