簡體   English   中英

全局對象和類的靜態成員

[英]Global objects and static members of class

我創建了一個有靜態成員的類。 每次創建對象時,我都希望在靜態成員中添加指向此對象的指針。

頭文件:

#include <vector>

class A
{
public: 
    A(const int pin);
    ~A();
    static std::vector<A*> channels;

private:
    int pin_number;
}

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);

 }

在main.cpp中我想聲明對象。 但是,當我聲明並初始化為全局變量時,它似乎不起作用:

A a1{ 1 };
A a2{ 2 };

int main() {
    std::cout << "Vector size: " << A::channels.size() << std::endl;
}

上面提到的代碼似乎不起作用。 在對象的構造函數中,我看到向量被填充。 在上述情況下輸出為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;
} 

樣本2:

int main() {
    A a1{ 1 };
    A a2{ 2 };

    std::cout << "Vector size: " << A::channels.size() << std::endl;
}

在上面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;
    }
}

所以你的初始化順序問題將得到解決。

注意:如果不清楚為什么這個解決方案有效,你可以查看這個答案 - 你的問題與實現單例模式的問題有關,並且在那里得到了深刻的解決。

A a1{ 1 };
A a2{ 2 };

int main() {
    std::cout << "Vector size: " << A::channels.size() << std::endl;
}

A a1 { 1 }; A a2 { 2 }; 具有全局創建的對象。 指針版本具有全局創建的指針,但堆上創建的對象不在全局空間中。 對於您的其他示例,這是相同的。 A類中的通道成員對A.cpp是靜態的,但是對象是在Main.cpp中全局創建的。 這意味着如果你想讓計數正確更新,你必須把std::vector<A*> A::channels; 進入main.cpp而不是A.cpp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM