Search code examples
c++mfcprivate-members

difference of variable in placement of private keyword in a MFC class


Using the following code snippet as an illustration to my question:

// #includes and other macros

class MyClass : public CFormView
{
private:
        DECLARE_DYNCREATE(MyClass)

        bool privateContent;

        ...

public:
        bool publicContent;

        ...
};

class MusicPlayer
{
public:
    AppClass *theApp;                   // which has a pointer accessing the MyClass object instantiated in the program

    ...
}

When I place the keyword "private" in MyClass definition as such, the privateContent member variable doesn't appear to be private when I try to access it in a method of MusicPlayer class. However, if I place the "private" keyword after the DECLARE_DYNCREATE(MyClass) line, the behavior of privateContent member variable returns to what is expected. Does anyone know why this is the case? Thanks in advance.


Solution

  • If you look at the definition of DECLARE_DYNCREATE, you will see that it uses another macro:

    // not serializable, but dynamically constructable
    #define DECLARE_DYNCREATE(class_name) \
        DECLARE_DYNAMIC(class_name) \
        static CObject* PASCAL CreateObject();
    

    And if you look at that macro, DECLARE_DYNAMIC, you'll see why your class turns public:

    #define DECLARE_DYNAMIC(class_name) \
    protected: \
        static CRuntimeClass* PASCAL _GetBaseClass(); \
    public: \
        static const CRuntimeClass class##class_name; \
        static CRuntimeClass* PASCAL GetThisClass(); \
        virtual CRuntimeClass* GetRuntimeClass() const; \
    

    When it expands, it's going to add that public: keyword, leaving the rest of your class definition public after that.

    So when you say say private: after DECLARE_DYNCREATE, you're then changing it from public to private.

    The usual use of this macro would be like this:

    class MyClass : public CFormView
    {
            DECLARE_DYNCREATE(MyClass)
    private:
            bool privateContent;
    
            ...
    
    public:
            bool publicContent;
    
            ...
    };
    

    The class will implicitly be private at the start, so the effect is the same.

    Also, most C++ programmers will agree you should start trying to get into the habit of placing your private variables at the bottom.

    The justification is that when people, including yourself, are reading the class, they will want to see what you can do with the class, which is in the public interface, rather than how the class is going to work, which is private.

    By putting the public interface first, you won't have to be bothered by all the private stuff.

    I used to put my private stuff at the top too (because I came from Visual Basic 6, before C++), and hated being told my privates should be on the bottom, but once you get into the habit you'll wish you changed sooner.