19

privateC++ でアクセス指定子の妥当性を試していました。ここに行きます:

インターフェース:

// class_A.h

class A
{
public:
    void printX();
private:
    void actualPrintX();
    int x;
};

実装:

// class_A.cpp
void A::printX()
{
    actualPrintX();
}

void A::actualPrintX()
{
    std::cout << x:
}

これを静的ライブラリ (.a/.lib) に組み込みました。これで、class_A.h と classA.a (または classA.lib) のペアができました。class_A.h を編集して削除しprivate:ました。

今別のクラスTester.cppで:

#include "class_A.h"    // the newly edited header

int main()
{
    A a;

    a.x = 12;           // both G++ and VC++ allowed this!
    a.printX();         // allowed, as expected
    a.actualPrintX();   // allowed by G++, VC++ gave a unresolved linker error

    return 0;
}

ライブラリのヘッダーを改ざんした後、すべての賭けがオフになることを知っています (つまり、システムの整合性など)。メソッドはハックされていますが、これは本当に許可されていますか? これをブロックする方法はありますか?それとも、ここで何か間違ったことをしていますか?

4

9 に答える 9

30

privateセキュリティメカニズムではありません。これは、意図を伝達し、プログラムの他の部分が知る必要のない情報を隠す方法であり、全体的な複雑さを軽減します。

2 つの異なるヘッダー ファイルを持つことは標準に準拠していないため、技術的には未定義の動作領域に入りますが、実際には、ほとんどのコンパイラは気にしません。

于 2010-02-16T13:18:33.273 に答える
7

いいえ。プライベート アクセス コントロールは、他の人があなたのデータや機能にアクセスするのを防ぐためのセキュリティ メカニズムとしてではなく、あなたが愚かなことをするのを防ぐためにあります。それを回避する方法はたくさんあります。

于 2010-02-16T13:18:51.710 に答える
5

私は試した。これは、1つのプライベートメソッドとパブリックメソッドを持つクラスTestを持つ私が書いたプログラムのnmです。

0000000100000dcc T __ZN4Test3barEv
0000000100000daa T __ZN4Test3fooEv

ご覧のとおり、署名はまったく同じです。リンカには、プライベートメソッドとパブリックメソッドを区別するものがまったくありません。

于 2010-02-16T13:32:49.703 に答える
5

私は他の答えのほとんどに同意します。

ただし、それを削除するときに、コンパイラがメンバーを物理的に異なる方法で配置することは完全に許容されることを指摘したいと思いますprivate。効果があればそれは運です。あなたはそれを頼りにすることはできません。両側が同じ宣言を使用していない場合、実際には同じクラスを使用していません。

于 2010-02-16T13:51:19.833 に答える
2

A::actualPrintX の実装はどこにもありません。それはあなたのリンカーエラーです。

于 2010-02-16T13:19:58.933 に答える
1

ほとんどの場合、プライベート メンバーをパブリックにするためにヘッダー ファイルを編集する必要さえありません。プリプロセッサでこれを行うことができます。このようなもの:

//"classWithPrivateMembers.hpp"
class C
{
private: //this is crucial for this method to work
    static int m;
};

int C::m = 12;

そして、これは機能します:

#define private public  
#include "classWithPrivateMembers.hpp"  
#undef private

int main()
{
    C::m = 34; // it works!
}
于 2010-02-16T19:21:01.380 に答える
1

また、メンバー変数のアクセスを変更すると、コンパイラはそれをクラス オブジェクト内の別のオフセットに配置する可能性があることにも注意してください。この標準により、コンパイラはメンバーを再配置する際にかなりの自由度を得ることができます (少なくとも同じアクセス レベル内では)。

于 2010-02-16T19:25:44.093 に答える