Variables 如何定义保留其作用域的宏';有人叫他
我正在尝试制作一个宏,以便更容易地定义属性 简化的示例,但目前我提供了一个带有公共get和私有set的属性:Variables 如何定义保留其作用域的宏';有人叫他,variables,visual-c++,scope,c++-cli,c-preprocessor,Variables,Visual C++,Scope,C++ Cli,C Preprocessor,我正在尝试制作一个宏,以便更容易地定义属性 简化的示例,但目前我提供了一个带有公共get和私有set的属性: #define propertyRO(xxType, xxName)\ property xxType xxName\ {\ xxType get() {return m___##xxName;}\ void set(xxType value) {m___##xxName = value;}\ }\ private:\
#define propertyRO(xxType, xxName)\
property xxType xxName\
{\
xxType get() {return m___##xxName;}\
void set(xxType value) {m___##xxName = value;}\
}\
private:\
xxType m___##xxName;\
然后要使用它,您可以这样做:
public ref class Wawawa
{
public:
int bob;
propertyRO(String^, MyName);
};
这可能会很好地工作,但它是有缺陷的,因为成员是在私有范围中指定的,这意味着在宏获得私有范围之后发生的任何事情。e、 g:
public ref class Wawawa
{
public:
int bob;
propertyRO(String^, MyName);
int fred; //ERROR HERE <- this would be private not public
};
public ref class Wawawa
{
公众:
int-bob;
propertyRO(字符串^,MyName);
int fred;//ERROR HERE在类定义的末尾插入属性宏调用(我同意,这个答案有点蹩脚;))我会回答:不要这样做。不要使用宏生成代码。这看起来会节省您的时间和精力,但您已经发现宏有问题,这对于阅读类声明的人来说肯定不是很明显。您可能很快会发现调试它是一场噩梦,因为调试器刚刚出现T位于宏行,而不是宏行中的代码
在我看来,咬紧牙关,把所有的属性全部写出来。我觉得这是不可能的
因此,更好的建议可能是将宏重命名为publicPropertyRO
,这将使其明显地创建公共属性。并将私有成员移动到属性声明上方:
#define publicPropertyRO(xxType, xxName)\
private:\
xxType m___##xxName;\
public:\
property xxType xxName\
{\
xxType get() {return m___##xxName;}\
void set(xxType value) {m___##xxName = value;}\
}\
这将使类处于公共:
状态,我认为这是可以接受的。
没有真正回答我的问题,但至少这是一个改进。问题的核心是propertyRO宏改变了引擎盖下的范围,对吗?问题不是它改变了范围本身,而是它以隐藏的方式完成,所以处理这个问题的最佳方法是公开它
是将public嵌入函数名中(这可能还可以),但另一种方法是将宏后面的作用域作为参数
#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:
。可以这样做在propertyRO宏的第一行添加一个“public:\”(无论如何这会更清晰)。私有属性可以类似地添加。这是真的。但我当然想知道是否有更好的方法可以工作,无论当前的作用域是什么:)调试器在调试时设法提取它(如果将鼠标悬停在Wawawa类型的对象上,可以看到MyName和m___MyName的当前值)。我确实同意你的观点,但这并不明显。当然,它会处理这些问题,但我的观点是调试器可能会将setter和getter视为在同一行-宏行上。因此,如果你尝试介入setter,调试器只会指向宏。如果你想更改其中一行的setter,你必须一些丑陋的宏粘贴需要手工完成,这会增加您的维护难题,这就是为什么我建议将其完整地写出来。关于在同一行,我现在明白您的意思,但我怀疑我是否会想要进入这个宏。至于维护难题,这就是制作这个被遗弃的宏的全部原因:)用C++/CLI编写带有私有集的属性所需的代码量太多了。有趣的是,我喜欢你的思维方式:)这似乎是最好的选择,但在“受保护”甚至“私有”区域使用宏的问题仍然存在。
public ref class Wawawa
{
public:
int bob;
propertyRO(String^, MyName, public);
int fred; // No error here, fred is public
};