我有一個叫頭filepaths.h它定義了一些靜態變量:爲什麼靜態變量需要在C++中聲明兩次
#ifndef FILEPATHS_H
#define FILEPATHS_H
class FilePaths {
public:
static QString dataFolder();
static QString profileFolder();
private:
static QString dataFolder_;
static QString profileFolder_;
};
}
#endif // FILEPATHS_H
而且我有一個相關的filepaths.cpp這一開始是這樣的:
#include "FilePaths.h"
QString FilePaths::dataFolder() {
return dataFolder_;
}
QString FilePaths::profileFolder() {
return profileFolder_;
}
但是沒有工作 - 我對所有的靜態變量得到了一個「未解決的符號錯誤」連接錯誤。所以我以這種方式添加這些變量到C++文件:
#include "FilePaths.h"
QString FilePaths::dataFolder_ = "";
QString FilePaths::profileFolder_ = "";
QString FilePaths::dataFolder() {
return dataFolder_;
}
QString FilePaths::profileFolder() {
return profileFolder_;
}
而這個工作,但是我不明白爲什麼。
爲什麼這些靜態變量需要定義兩次?或者,也許我沒有定義他們,但初始化他們?但仍然爲什麼需要這樣做?還是應該以不同的方式寫我的課程?
我不認爲這是古老的。聲明聲稱「存在某個名爲X的變量/類/函數」,而定義說「X駐留在這裏,編譯器請爲它分配存儲空間」。分離聲明和定義的能力是允許多種翻譯單元採用靜態類型的語言,而編譯器不需要過度「聰明」並猜測自己的意圖。 – vsekhar
這並不是很陳舊,因爲這兩個標準(甚至現在,C99/C++ 11)在實際的鏈接器進程上都非常模糊,並且某個cpp文件中的定義將導致生成的目標文件中有一個定義,如果這並非如此,鏈接器在將所有代碼鏈接在一起時不會找到唯一的引用。 – rubenvb
vsekhar,@rubenvb:我會注意到,對於模板代碼,我們獲得了函數和靜態屬性的多個定義(在對象文件中),但鏈接器管理它們是正確的。 –