Почему я не могу использовать статические члены, например статические структуры, в своих классах в VS2008?

StackOverflow https://stackoverflow.com/questions/272161

Вопрос

Когда я пишу такой код в 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";
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top