Sebastian Dwornik
Sebastian Dwornik

Reputation: 2576

How to properly use structs inside a class?

Using: VS2008, Win32, C/C++

I'm trying to encapsulate my entire dialog window into a class for reusability. Sort of like a custom control. In doing this, I am moving my seperate functions into a class. The following struct design though is giving me problems, with Visual Studio outputting: error C2334 '{'.

It's a simple message map layout. But I can't seem to escape this C2334 error. :(

Here is my class code snippet.

class CScrollingListDlg
{
private:

LRESULT DoCommandMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT DoPaintMain   (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT DoAnimationTimer (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT DoHandleTouch (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);

//
// message maps
//
// Generic defines and data types.
struct decodeUINT {
    UINT Code;
    LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM);
};

struct decodeCMD {
    UINT Code;
    LRESULT (*Fxn)(HWND, WORD, HWND, WORD);
};

// WM_Message dispatch table for MainWndProc.

//
// ***  error C2334 '{'  ***
//
const struct decodeUINT MainMessages[] = {
    WM_PAINT,   DoPaintMain,
    WM_DESTROY, DoDestroyMain,
    WM_QUIT,    DoDestroyMain,
    WM_COMMAND, DoCommandMain,
};


};

What am I missing here?

Thanks.

Upvotes: 3

Views: 6101

Answers (2)

j_random_hacker
j_random_hacker

Reputation: 51326

You cannot specify initialisers for non-static members that way -- you would normally need to declare the array and then populate it inside the constructor... Except that, in fact there is no way to initialise const member arrays in C++ (see this thread).

If you are prepared to share MainMessages amongst all instances of CScrollingListDlg (which I suspect was your intention all along), you should make it static, in which case you can declare:

static const decodeUINT MainMessages[];  // "struct" keyword unnecessary

inside the class definition of CScrollingListDlg, and then define it outside the class:

const CScrollingListDlg::decodeUINT CScrollingListDlg::MainMessages[] = {
    WM_PAINT,   DoPaintMain,
    WM_DESTROY, DoDestroyMain,
    WM_QUIT,    DoDestroyMain,
    WM_COMMAND, DoCommandMain,    // The comma *is* allowed -- thanks Josh!
};

In order for this to actually compile, you'll need to make DoPaintMain(), DoDestroyMain(), etc. static as well -- as it stands, they are all per-object methods that implicitly take a this pointer, so they can't actually be contained in a function pointer of type LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM). (You could leave them as non-static methods and change the pointer type in decodeUINT to a pointer-to-member-function type, but that's probably not what you want.)

[EDIT: Thanks to Josh for some helpful comments!]

Upvotes: 5

Cătălin Pitiș
Cătălin Pitiș

Reputation: 14327

You can't initialize an array member inside a class declaration. You should only declare MainMessages, then initialize it in the constructors of the class.

I also recommend using std::vector instead of array. This way, decodeUINT declaration becomes:

std::vector<decodeUINT> MainMessages;

and in constructor, use std::vector::push_back method to insert content.

If you need access to the memory managed by the vector, use &MainMessages[0].

Upvotes: 5

Related Questions