简体   繁体   中英

Why can't I use static members, for example static structures, in my classes in VS2008?

When I write code like this in 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() {}
};

I then initialize my structure like this:

.cpp
string QueryValidate::pts::ptCreate = "something";
string QueryValidate::pts::ptDelete = "something";
//...

The compiler gives the following errors:

'Patterns': the symbol to the left of a '::' must be a type 'ptSelect' : is not a member of 'QueryValidate'

What am I doing wrong? Is this a problem with Visual Studio or with my code? I know that static members except for const ones must be defined outside the class they were declared in.

You're trying to create a non-static member (ptCreate) of a static member (pts). This won't work like this.

You got two options, either use a struct initializer list for the Patterns class.

Patterns QueryValidate::pts = {"CREATE", "DELETE"}; // etc. for every string

Or, much safer (and better in my opinion), provide a constructor in Patterns and call that one.

struct Patterns {
   Patterns() { /*...*/ }
   /* ... */
}

On a side not, your code wouldn't work in any C++ compiler, it's not a conflict with Visual Studio things.

您只能将结构初始化为一个整体,如:

Patterns QueryValidate::pts = { "something", "something", ... };

This isn't valid C++. In the cpp file you're declaring parts of the static structure "QueryValidate::pts", but that's not allowed: you've got to declare the whole structure, like so:

Patterns QueryValidate::pts;

if you want members to be initialized, you either initialize them in another method, or add a constructor to Patterns that takes whatever initialization arguments you want.

I'm not real sure what you are trying to do here. It looks kind of like you are trying to declare and initialize each field in pts separately, rather than declare pts once as a single object. I'm really surprised VS lets you do that.

What worked for me in gcc was the following:

Patterns QueryValidate::pts;

void foo () {
    QueryValidate::pts.ptCreate = "something";
    QueryValidate::pts.ptDelete = "something";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM