为什么“#if !(protected) and !(private)”不能防御“#define private public”?
why "#if !(protected) and !(private)" cannot defense "#define private public"?
我尝试一些方法来防止有人像这样强制私有 public:
#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的private成员,也就是说private已经变成了public。但是为什么A还能定义?
您永远不应该 #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++ 并没有真正为您提供弹药来防止用户入侵您的库。不遵守规则的用户会在伤害你之前先伤害自己……只需明确表示不支持古怪的程序即可。即使那样也应该是不必要的,不用说。
行
#if !(protected) and !(private)
在预处理阶段进行评估。在此阶段,protected 和 private 被视为预处理标记,而不是关键字。 private 被替换为 public,因为您已经这样定义了它。然后将 protected 和 public 的实例替换为 0,因为一旦完成所有宏替换,所有剩余的标识符将始终替换为 0。所以这些行变为
#if !(0) and !(0)
#define A 1
#endif
其中大部分内容的详细信息可以在 C99 的 6.10.1 第 4 段和 C++11 的 16.1 第 4 段中找到。
private
、protected
和 public
部分旨在防止意外滥用。它们不能用于防止故意滥用。
用户更改很简单
class B{
private:
int c;
};
到
class B{
public:
int c;
};
或
class B{
private:
friend class UserClass;
int c;
};
以访问 B
的私人部分。
不要在这些事情上浪费精力
我尝试一些方法来防止有人像这样强制私有 public:
#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的private成员,也就是说private已经变成了public。但是为什么A还能定义?
您永远不应该 #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++ 并没有真正为您提供弹药来防止用户入侵您的库。不遵守规则的用户会在伤害你之前先伤害自己……只需明确表示不支持古怪的程序即可。即使那样也应该是不必要的,不用说。
行
#if !(protected) and !(private)
在预处理阶段进行评估。在此阶段,protected 和 private 被视为预处理标记,而不是关键字。 private 被替换为 public,因为您已经这样定义了它。然后将 protected 和 public 的实例替换为 0,因为一旦完成所有宏替换,所有剩余的标识符将始终替换为 0。所以这些行变为
#if !(0) and !(0)
#define A 1
#endif
其中大部分内容的详细信息可以在 C99 的 6.10.1 第 4 段和 C++11 的 16.1 第 4 段中找到。
private
、protected
和 public
部分旨在防止意外滥用。它们不能用于防止故意滥用。
用户更改很简单
class B{
private:
int c;
};
到
class B{
public:
int c;
};
或
class B{
private:
friend class UserClass;
int c;
};
以访问 B
的私人部分。
不要在这些事情上浪费精力