开发者

How to define a macro that retains its scope after it's been called

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: keywo开发者_StackOverflow社区rd in a macro, without it affecting the rest of the class?


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


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.


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.


The core of the problem is that the propertyRO macro changes the scope under the hood, right? The problem is not that it changes scope per se, but that it is done in a hidden way, so the best way to handle this is to expose it.

Demoncodemonkey's suggestion is to embed public into the name of the function (which might be OK), but an alternative is to make the scope following the macro a parameter. E.g.

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

...

public ref class Wawawa
{
public:
    int bob;
    propertyRO(String^, MyName, public);
    int fred; // No error here, fred is public
};

The syntax and naming is not super good, but it makes sure that it is not possible to use this macro without consciously making a decision about what the scope should be after the function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜