web-dev-qa-db-ja.com

Staticメソッドは同じクラスのプライベートメソッドにアクセスできますか?

この質問は、シングルトン/名前付きコンストラクタのためにあります。どちらの場合も、実際のコンストラクターは保護されているかプライベートであり、どちらからも外部からアクセスできません。

たとえば、短い名前のコンストラクタは次のとおりです。

_ class A
{
  public:
    static A createA() { return A(0); } // named constructor
  private:
    A (int x);
};
int main(void)
{
   A a = A::createA(); 
}
_

静的メソッドは静的データメンバーにのみアクセスできるか、既存のオブジェクトを介してプライベートデータ/メソッドにアクセスできると思いました。ただし、上記のコードでは、プライベートコンストラクターA()は静的ではなく、呼び出されているときにはオブジェクトも存在しません。だから私が考えることができる唯一の説明は、静的メソッドが同じクラスの非静的プライベートメソッドにアクセスできるということです。誰かが私の考えを肯定または否定することができますか?

これはあまりにも些細なことですが、キーワードがあまりにも一般的であり、数十のグーグルページで答えを見つけることができなかった場合は申し訳ありません。前もって感謝します。

16
Flowing Cloud

静的メンバー関数には、非静的メンバー関数と同じアクセス権があります。そのため、クラス内のパブリック変数、保護変数、およびプライベート変数にアクセスできます。ただし、関数がメンバーにアクセスできるようにするには、クラスのインスタンスを関数に渡す必要があります。それ以外の場合、静的関数はクラス内の他の静的メンバーにのみ直接アクセスできます。

11
NathanOliver

標準に従って§11/ p2メンバーアクセス制御[class.access] (Emphasis Mine)

クラスのメンバーは、クラスがアクセスできるすべての名前にもアクセスできます。メンバー関数のローカルクラスは、メンバー関数自体がアクセスできる名前と同じ名前にアクセスできます。113

113)したがって、アクセス許可は、ネストされたローカルクラスに対して推移的かつ累積的です。

静的メンバー関数はクラスのメンバーであるため、クラスがアクセスできるすべての名前にアクセスできるため、クラス自体のコンストラクターにアクセスできます。

したがって、あなたの例では:

_class A {
  A(int x);  
public:
  static A createA() { return A(0); } // named constructor  
};
_

静的メンバー関数A::createA()は、privateコンストラクターA::A(int)を呼び出すためのアクセス権を持ちます。

7
101010

クラスの関数(static関数を含む)内で、allは、異なるインスタンスを扱っている場合でも、privateメンバーデータと関数にアクセスできますその関数内のそのクラスの。

copy constructorsおよびassignment operatorを記述するときに、これをよく利用します。

(私の上司は、ある種のfriend = delete;構文を使用してこの動作を無効にしたい方法についてよく話します。)

はい、できます。静的関数はプライベートメンバーにアクセスできますが、それ以外はクラスの外部で定義された関数とまったく同じです。特に、thisポインターがない(つまり、特定のインスタンスに「バインド」されていない)ため、メンバーに直接アクセスすることはできません(常にメンバーに「バインド」されています)インスタンス):それをしたい場合は、どこかからインスタンスが必要です:

#include <iostream>
using namespace std;

class A
{
  public:
    static A createA() { return A(0); }
    static void dosomething(A *a) { return a->something(); }
  private:
    A (int x) { cout << "ctor" << endl; }
    void something() { cout << "something" << endl; }
};

int main(void)
{
   A a = A::createA(); 
   A::dosomething(&a); 
   return 0;
}
1
rainer

静的メソッドは、既存のインスタンスの静的メンバーや非静的メンバーにアクセスしていません。
新しいインスタンスを作成しています。

0
Robert Kock