2011-08-11 34 views
4

在下面的程序中我已经使用了静态const int init。但它是抛出错误 /tmp/ccEkWmkT.o(.text+0x15d):在函数check::operation()': : undefined reference to检查::初始化'使用编译时常量抛出错误

此错误是只有当使用矢量。有人可以帮忙吗?什么是确切的行为?

#include<vector> 
#include<iostream> 
using namespace std; 

class check{ 
static const int init=1; 
public: 
    check(){} 
    void operation(); 
}; 

void check::operation(){ 
    vector<int> dummy; 
    dummy.push_back(init); 
} 

int main(){ 
    check ck; 
    ck.operation(); 
} 
+0

+1,不错的角落案例。 – iammilind

回答

0

如果你通过引用传递它是“使用”,你可能必须在.cpp文件中定义,以便它得到一个 地址。

如果你只是使用常量的值,你可能会逃避不定义它。

+0

好的,是的,我明白了。非常感谢解释。 – mandeep

1

您对提供类的外部静态成员的定义(在的.cpp文件)为:

//check.h (same as before) 
class check 
{ 
    static const int init=1; //declaration and in-class initialization 
public: 
    check(){} 
    void operation(); 
}; 

然后在check.cpp文件,这样做:

//check.cpp 
#include "check.h" 

const int check::init; //definition 
3

“确切的行为是什么?”

问题是push_back需要一个参考参数。您可以使用static const int成员变量的而不提供对象的单独定义,但不能使用对对象本身的引用(因为它不存在)。 “使用”成员本身的含义在一个定义规则3.2/2的标准部分中定义。

一个解决方法是在只有一个翻译单元提供了一个定义:

const int check::init; 

如果你这样做,你也可以选择从声明的= 1初始化(类内部)移动到定义(课外)。

另一个解决方法是创建一个从成员变量的临时(在此仅使用值,它并不关心其中对象位于并因此不关心它是否存在),然后传递到临时的参考:

dummy.push_back(int(init)); 

当然还有一个潜在的维护问题上都存在,如果类型initdummy两个变化,比方说,long long [*],并从1值变化的东西比INT_MAX更大,那么你有麻烦了。因此,您可以使用+init,因为一元+运算符也会为其结果创建一个临时值。不过,读者和未来的维护者可能会有点困惑。

[*]假设您的实施有long long

+0

当然最简单的方法是将'init'定义为'enum {init = 1; }。不能用很长很长使用,但除此之外,它并不需要单独定义,从来没有得到存储,如果它需要一个编译器总是创建适当的临时自动。 –

+0

我见过的另一种选择(不是我推荐它)在像'check :: init + 0'这样的表达式中使用静态常量。该增加不需要左值,因此该成员不被视为*使用*。 –

+0

@Jan:好点。假定程序中没有任何地方真的需要使用'check :: init'具有地址的事实。很可能,因为否则在程序中会出现比这个错误更多的错误,但我没有做到这一点:-) –