我在尝试:
class MyClass {
public:
MyClass();
int myID;
static int currentID;
};
MyClass::MyClass() {
myID = currentID;
++currentID;
}
我正在尝试为此类的所有实例分配一个唯一ID。
编辑:
它对我不起作用。我在xcode中得到了两个:
未定义的符号: “GameObject :: currentID”,引自: GameObject.o中的__ZN10GameObject9currentIDE $ non_lazy_ptr (也许你的意思是:__ ZN10GameObject9currentIDE $ non_lazy_ptr) ld:找不到符号 collect2:ld返回1退出状态
答案 0 :(得分:5)
对我有用:
#include <iostream>
class My
{
public:
My() : id(++currentId) {}
int id;
static int currentId;
};
int My::currentId = 0;
std::ostream & operator<<(std::ostream & os, My & m)
{
return os << m.id;
}
int main()
{
My a;
My b;
My c;
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
}
输出:
> ./x
1
2
3
答案 1 :(得分:3)
除了其他案例外,它还适用于以下情况:
MyClass a[10];
MyClass* b = new MyClass[10];
如果使用STL容器来保存MyClass
个对象,请务必小心。 可能与您预期的行为不一样,但很难找到问题。请参阅以下示例:
int MyClass::currentID = 0;
...
std::vector<MyClass> c(10);
MyClass a;
在这种情况下,结果如下:
c[0].myID = 0;
c[1].myID = 0;
....
c[9].myID = 0
=============
a.myID = 1.
默认构造函数只执行一次。原因是std :: vector的构造函数将使用相同的值来初始化向量的所有元素。在我的系统中,std :: vector的构造函数如下:
explicit
vector(size_type __n, const value_type& __value = value_type(),
const allocator_type& __a = allocator_type())
: _Base(__n, __a)
{ _M_fill_initialize(__n, __value); }
_M_fill_initialize
将使用__value
(来自默认构造函数value_type()
)__n
次来初始化分配的内存。
上面的代码最终将调用uninitialized_fill_n
,其执行以下操作:
for (; __n > 0; --__n, ++__cur)
std::_Construct(&*__cur, __x);
以下是std::_Contruct
:
template<typename _T1, typename _T2>
inline void
_Construct(_T1* __p, const _T2& __value)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_]allocator::construct
::new(static_cast<void*>(__p)) _T1(__value);
}
在这里你可以看到它最终调用全局运算符new
来使用相同的值初始化向量中的每个元素。
结论是,使用静态成员到初始数据成员将在大多数情况下工作,但如果您打算在STL容器中使用它,它可能会失败,并且很难找到问题。我只尝试std::vector
,当使用其他类型的带有MyClass
对象的stl容器时,很可能存在问题。
答案 2 :(得分:1)
您收到错误的原因不是因为您正在从构造函数中访问静态,这是合法的btw,但是因为您没有定义它。
class My
{
public:
My() : id(++currentId) {}
int id;
static int currentId;
};
//place the definition in the implementation file
int My::currentId = 0;
答案 3 :(得分:0)
是的,没有问题,只要你没有MyClass的静态实例。
答案 4 :(得分:0)
是的,没关系。但是你编写的代码不是线程安全的:可以在不同的线程中同时实例化2个类。在第一个实例有时间增加静态变量之前,第二个实例可以获取currentID
的相同值。
这对您来说可能是也可能不是问题。
如果您需要线程安全,this question应该有帮助。
答案 5 :(得分:0)
int MyClass::currentID=0;
如果没有完成,您需要在CPP文件中执行此操作
答案 6 :(得分:0)
您需要确保在类之外定义和初始化类的静态成员。这对我有用:
#include <iostream>
class MyClass {
private:
int myID;
static int currentID;
public:
//default constructor
MyClass()
: myID(currentID)
{
++currentID;
}
void printId() { std::cout << "Object Id :" << myID << std::endl; } /*Prints the unique ID assigned to each object.*/
};
// define the static class member here:
int MyClass::currentID = 1;
int main()
{
MyClass m1, m2, m3;
m1.printId();
m2.printId();
m3.printId();
}
输出:
对象ID:1
对象ID:2
对象ID:3