我创建了一个有静态成员的类.每次创建对象时,我都希望在静态成员中添加指向此对象的指针.
头文件:
#include <vector>
class A
{
public:
A(const int pin);
~A();
static std::vector<A*> channels;
private:
int pin_number;
}
Run Code Online (Sandbox Code Playgroud)
cpp文件:
#include "A.h"
std::vector<A*> A::channels;
A::A(const int pin) : pin_number(pin) { A::channels.push_back(this); };
A::~A() {
std::vector<A*>::iterator ch = std::find(A::channels.begin(), A::channels.end(), this);
if (ch != A::channels.end()) {
A::channels.erase(ch);
}
Run Code Online (Sandbox Code Playgroud)
在main.cpp中我想声明对象.但是,当我声明并初始化为全局变量时,它似乎不起作用:
A a1{ 1 };
A a2{ 2 };
int main() {
std::cout << "Vector size: " << A::channels.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
上面提到的代码似乎不起作用.在对象的构造函数中,我看到向量被填充.在上述情况下输出为0.
但是,对于下面的2个代码示例,似乎确实有效.
样本1:
A *a1;
A *a2;
int main() {
a1 = new A{ 1 };
a2 = new A{ 2 };
std::cout << "Vector size: " << A::channels.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
样本2:
int main() {
A a1{ 1 };
A a2{ 2 };
std::cout << "Vector size: " << A::channels.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在上面2例中,它打印2,这是我的预期.
任何人都可以帮我解释我做错了什么,或者我错过了什么.我猜它必须对对象的范围做一些事情,但我似乎无法理解为什么第一个例子不起作用.
编辑:我没有为该类添加析构函数,因为我认为它与此问题无关.
对于全局对象,您有经典问题 - 来自不同编译单元的全局对象的初始化顺序是未定义的,因此在这种情况下,您的向量似乎在创建这两个实例后初始化.解决方案是拥有静态局部向量:
class A
{
public:
A(const int pin) { A::channels().push_back(this); };
static std::vector<A*> &channels()
{
static std::vector<A*> theInstance;
return theInstance;
}
}
Run Code Online (Sandbox Code Playgroud)
所以你的初始化顺序问题将得到解决.
注意:如果不清楚为什么这个解决方案有效,你可以查看这个答案 - 你的问题与实现单例模式的问题有关,并且在那里得到了深刻的解决.
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |