全局对象和类的静态成员

Bob*_*Bob 2 c++ c++11 c++14

我创建了一个有静态成员的类.每次创建对象时,我都希望在静态成员中添加指向此对象的指针.

头文件:

#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,这是我的预期.

任何人都可以帮我解释我做错了什么,或者我错过了什么.我猜它必须对对象的范围做一些事情,但我似乎无法理解为什么第一个例子不起作用.

编辑:我没有为该类添加析构函数,因为我认为它与此问题无关.

Sla*_*ica 8

对于全局对象,您有经典问题 - 来自不同编译单元的全局对象的初始化顺序是未定义的,因此在这种情况下,您的向量似乎在创建这两个实例后初始化.解决方案是拥有静态局部向量:

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)

所以你的初始化顺序问题将得到解决.

注意:如果不清楚为什么这个解决方案有效,你可以查看这个答案 - 你的问题与实现单例模式的问题有关,并且在那里得到了深刻的解决.