2

如果我有这样的课,

class Sample
{
private:
      int X;
};

然后我们不能从外部访问 X,所以这是非法的,

    Sample s;
    s.X = 10; // error - private access

但是我们可以在不编辑类的情况下使其可访问!我们需要做的就是这个,

#define private public  //note this define!

class Sample
{
private:
      int X;
};

//outside code
Sample s;
s.X = 10; //no error!

ideone 的工作代码:http ://www.ideone.com/FaGpZ

这意味着,我们可以通过在类定义之前或之前定义此类宏来更改访问说明符#include <headerfile.h>

#define public private //make public private
//or
#define protected private //make protected private
//or
#define so on

这不是 C++(宏/访问说明符/其他)的问题吗?

无论如何,这个话题的重点是:

使用宏,我们很容易违反封装。访问说明符并非万无一失!我对吗?

4

5 回答 5

7

首先,这样做是违法的。private是关键字,不能在宏中用作标识符;你的程序格式不正确。

但无论如何,这根本不是宏的问题。愚蠢地使用它们的傻瓜。:) (它们的存在是为了帮助您确保安全,它们不是为了帮助您确保安全并阻止对它们的所有访问,无论您尝试什么。C++ 可以防止墨菲,而不是马基雅维利。)

请注意,您可以以格式良好且定义明确的方式访问私有,如此处所示。再说一次,这不是语言的问题,只是语言的工作不是做更多的事情来保持窥探。

于 2010-12-26T08:58:21.963 回答
6

但是我们可以在不编辑类的情况下使其可访问!我们需要做的就是这个,

从技术上讲,您所展示的只是“我们可以将合法程序转变为未定义行为”,而无需编辑特定类。

这几乎不是新闻。您也可以通过在末尾添加这样的一行来将其转换为未定义的行为main()

int i = 0;
i = ++i;

C++ 中的访问说明符不是一项安全功能它们不能防止黑客攻击,也不能防止人们故意将错误引入您的代码。

它们只是允许编译器帮助您维护某些类不变量。如果您不小心尝试访问私有成员,就好像它是公共的一样,它们允许编译器通知您。您所展示的只是“如果我专门尝试破坏我的程序,我可以”。希望这绝对不会让任何人感到意外。

正如@Gman 所说,在 C++ 语言中重新定义关键字是未定义的行为。它似乎可以在您的编译器上运行,但它不再是定义良好的 C++ 程序,并且编译器原则上可以做它喜欢的任何事情。

于 2010-12-26T10:05:31.863 回答
3

但是我们可以在不编辑类的情况下使其可访问

并非没有编辑包含该类的源文件。

是的,宏让你在脚下开枪。这几乎不是新闻......但这是一个特别不令人不安的例子,至于“违反封装”,你必须强制类要么定义骨头宏本身,要么包含一个这样做的头文件。

换句话说:你能看到这是一个真正的、负责任的软件开发中的问题吗?

于 2010-12-26T09:05:16.227 回答
0

@Nawaz,您的帖子很有趣,我以前从未想过这一点。但是,我相信您的问题的答案很简单:将 C++(或任何语言)安全性视为组织代码的一种方式,而不是一种警察。

基本上,由于所有变量都是在您自己的代码中定义的,因此无论您在哪里定义它们,您都应该能够访问它们。所以你不应该对你找到一种访问私人成员的方法感到惊讶。

实际上,还有一种更简单的方法可以访问私有变量。假设您有一个包含此类的库:

class VerySecure
{
private:
    int WorldMostSecureCode;
};

假设我在我的代码中使用了你非常安全的类。我可以通过这种方式轻松访问私有成员:

VerySecury a;
int *myhacker = (int*)(&a);
int b = (*myhacker);
printf("Here is your supposed world secret: %d :-) \n", b);

那个怎么样?!!

于 2010-12-26T10:51:30.563 回答
-1

不,它会破坏私有方法。如果编译器能够告诉这些私有方法不能在其他地方访问,那么它们可以被内联和优化,并且它们可能不会出现在目标文件中,因此它们将无法访问。

以此为例。它可以工作,不能链接或不能运行可执行文件,具体取决于您使用的优化/剥离标志以及您如何编译事物(即,您可以将实现放在共享库中与否)

class A {
// i need this one ...
private:
        void stupid_private();
public:
        void unlock(std::string password);
};

实现文件:

#include <iostream>
#include "a.h++"

// uncomment this for more g++ fun
// __attribute__((visibility("hidden")))
void A::stupid_private() {
        std::cout << "let's output something silly." << std::endl;
}
void A::unlock(std::string password) {
        if (password == "jumbo")
                stupid_private();
}

用户文件:

#define private public
#include "a.h++"

int main() {
        A a;
        a.stupid_private();
        return 0;
}
于 2010-12-26T09:58:02.200 回答