Почему я не могу использовать статические члены, например статические структуры, в своих классах в VS2008?
-
07-07-2019 - |
Вопрос
Когда я пишу такой код в VS 2008:
.h
struct Patterns {
string ptCreate;
string ptDelete;
string ptDrop;
string ptUpdate;
string ptInsert;
string ptSelect;
};
class QueryValidate {
string query;
string pattern;
static Patterns pts;
public:
friend class Query;
QueryValidate(const string& qr, const string& ptn):
query(qr), pattern(ptn) {}
bool validate() {
boost::regex rg(pattern);
return boost::regex_match(query, rg);
}
virtual ~QueryValidate() {}
};
Затем я инициализирую свою структуру следующим образом:
.cpp
string QueryValidate::pts::ptCreate = "something";
string QueryValidate::pts::ptDelete = "something";
//...
Компилятор выдает следующие ошибки:
'Patterns': символ слева от '::' должен иметь тип 'ptSelect' : не является членом QueryValidate
Что я делаю не так? Это проблема с Visual Studio или с моим кодом? Я знаю, что статические члены, кроме константных, должны быть определены вне класса, в котором они были объявлены.
Решение
Вы пытаетесь создать нестатический член (ptCreate) из статического члена (pts). Это не будет работать так.
У вас есть два варианта, либо использовать список инициализатора структуры для класса Patterns.
Patterns QueryValidate::pts = {"CREATE", "DELETE"}; // etc. for every string
Или, что намного безопаснее (и, на мой взгляд, лучше), предоставьте конструктор в Patterns и назовите его.
struct Patterns {
Patterns() { /*...*/ }
/* ... */
}
С другой стороны, ваш код не будет работать ни в одном компиляторе C ++, это не противоречит вещам Visual Studio.
Другие советы
Вы можете только инициализировать структуру в целом, как в:
Patterns QueryValidate::pts = { "something", "something", ... };
Это недопустимо в C ++. В файле cpp вы объявляете части статической структуры " QueryValidate :: pts " ;, но это недопустимо: вам нужно объявить всю структуру, как показано ниже:
Шаблоны QueryValidate :: pts;
если вы хотите, чтобы члены были инициализированы, вы либо инициализируете их в другом методе, либо добавляете конструктор в Patterns, который принимает любые аргументы инициализации, которые вы хотите.
Я не совсем уверен, что вы пытаетесь сделать здесь. Похоже, вы пытаетесь объявить и инициализировать каждое поле в pts отдельно, а не объявлять pts один раз как один объект. Я очень удивлен, что VS позволяет вам это делать.
В gcc у меня сработало следующее:
Patterns QueryValidate::pts;
void foo () {
QueryValidate::pts.ptCreate = "something";
QueryValidate::pts.ptDelete = "something";
}