views:

91

answers:

3

I'm trying to make a macro to make it easier to define properties.

Simplified example but at the moment I have this to provide a property with a public get and private set:

#define propertyRO(xxType, xxName)\
    property xxType xxName\
    {\
        xxType get() {return m___##xxName;}\
        void set(xxType value) {m___##xxName = value;}\
    }\
    private:\
        xxType m___##xxName;\

and then to use it you would do this:

public ref class Wawawa
{
public:
    int bob;
    propertyRO(String^, MyName);
};

This would potentially work great, but it's flawed because the member is specified in private scope, which means anything that occurs after the macro also gets private scope. e.g:

public ref class Wawawa
{
public:
    int bob;
    propertyRO(String^, MyName);
    int fred; //ERROR HERE <- this would be private not public
};

So if you ignore what this macro actually does, my real question is: is there any way to use the private: keyword in a macro, without it affecting the rest of the class?

+2  A: 

Insert your property macro calls all together at the end of the class defintion. (And I agree, that this answer is kind of lame ;))

Danvil
Still no good if you have multiple properties that you want to be public... you'd have to add a `public:` between each one.
demoncodemonkey
Well that can be solved with adding a "public:\" at the first line of the propertyRO macro (which would be clearer anyway). Private properties could be added analogous.
Danvil
True. But of course I'm wondering if there's a better way that will work whatever the current scope is :)
demoncodemonkey
+3  A: 

I would answer: just don't do this. Don't use macros to generate code. It looks like it's going to save you time and effort, but you've already found that the macro has a problem, which is certainly not obvious to someone reading the class declaration. You may also soon find that debugging it is a nightmare, since the debugger just points at the macro line, not the code inside it.

IMO, bite the bullet and just write out all the properties in full.

AshleysBrain
Well the debugger manages to pick it up while debugging (if you hover over an object of type Wawawa, you can see the current values of MyName and m___MyName). I do take your point about it not being obvious though.
demoncodemonkey
Sure, it'll pick those up, but my point was the debugger probably treats the setters and getters as being on the same line - the macro line. So if you try to step in to the setter, the debugger will just point at the macro. And if you want to change the setter for one of those, you'll have some ugly macro-pasting to do by hand, which adds to your maintenance woes, which is why I recommend writing it out in full.
AshleysBrain
About being on the same line, I now see what you're saying but I doubt I'd ever want to step into this macro. And as for maintenance woes, that's the whole reason for making this godforsaken macro in the first place :) The amount of code you have to write in C++/CLI to make a property with a private set is just insane.
demoncodemonkey
+1  A: 

I have a feeling this isn't going to be possible.

So maybe a better proposal would be to rename the macro to publicPropertyRO, which would make it obvious it will create a public property. And move the private member to be above the property declaration:

#define publicPropertyRO(xxType, xxName)\
    private:\
        xxType m___##xxName;\
    public:\
        property xxType xxName\
        {\
            xxType get() {return m___##xxName;}\
            void set(xxType value) {m___##xxName = value;}\
        }\

This would then leave the class in a public: state, which I think is acceptable.
Not really answered my question, but at least it's an improvement.

demoncodemonkey