[英]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.