我试着阻止某人像这样强迫私人公开:
#define private public
#if !(protected) and !(private)
#define A 1
#endif
class B{
private:
int c;
};
int main(){
int a=A;
B b;
b.c=2;
};
一开始我认为这段代码无法编译,因为
#define private public
会触发
#if !(protected) and !(private)
防止A定义。但实际上这段代码可以编译,但同时我可以直接访问B的私有成员,这意味着私有已经公开。但为什么A仍然可以定义?
答案 0 :(得分:3)
您永远不应#define
private
之类的关键字。如果您包含来自同一.cpp
文件的标准库的任何部分(甚至是<new>
或<initializer_list>
等基本语言功能所需的部分),则行为未定义。
也就是说,当#if
计算其表达式时,任何标识符或关键字标记都被视为数字零。解释如下:
#if !(protected) and !(private)
#if !(protected) and !(public)
#if !(0) and !(0)
#if true
您可能正在寻找defined
运算符,该运算符会告诉您其操作数是否为宏。
#if ! defined(protected) and ! defined(private)
但是,不要这样做。
如果您的目标是阻止某人黑客攻击关键字,可以这样做:
#if defined(protected) || defined(private) || …
# error Do not hack keywords!
#endif
这对于防御性编码来说太过分了。 C ++并没有真正为您提供防止用户攻击您的库的弹药。不遵守规则的用户会在伤害你之前伤害自己......只需明确表示不支持奇怪的程序。即便如此,也是不必要的,不言而喻。
答案 1 :(得分:0)
该行
typedef struct _charformat2 {
UINT cbSize;
DWORD dwMask;
DWORD dwEffects;
LONG yHeight;
LONG yOffset;
COLORREF crTextColor;
BYTE bCharSet;
BYTE bPitchAndFamily;
TCHAR szFaceName[LF_FACESIZE];
WORD wWeight;
SHORT sSpacing;
COLORREF crBackColor;
LCID lcid;
#if (_RICHEDIT_VER >= 0x0500)
union {
DWORD dwReserved;
DWORD dwCookie;
};
#else
DWORD dwReserved;
#endif
SHORT sStyle;
WORD wKerning;
BYTE bUnderlineType;
BYTE bAnimation;
BYTE bRevAuthor;
#if (_RICHEDIT_VER >= 0x0800)
BYTE bUnderlineColor;
#endif
} CHARFORMAT2;
在预处理阶段评估。在此阶段,protected和private被视为预处理令牌,而不是关键字。 private已被public替换,因为您已将其定义为public。然后将protected和public的实例替换为0,因为一旦完成所有宏替换,所有剩余的标识符总是被0替换。所以行变为
#if !(protected) and !(private)
大部分细节可以在C99的6.10.1第4段和C ++ 11的16.1第4段中找到。
答案 2 :(得分:0)
private
,protected
和public
部分旨在防止意外滥用。它们不能用于防止故意滥用。
用户更改
是微不足道的class B{
private:
int c;
};
到
class B{
public:
int c;
};
或
class B{
private:
friend class UserClass;
int c;
};
可以访问B
的私人部分。
不要在这些事情上浪费精力。