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++はMachiavelliではなくMurphyから保護します。)

here に示されているように、整形式で明確に定義された方法でプライベートにアクセスできることに注意してください。繰り返しますが、これは言語の問題ではありません。単に、手を出し続けるために必要以上のことをするのは、言語の仕事ではありません。

于 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 に答える