1

以下のようなコードに出くわしました。これは基本的に、クラス コンストラクターをプライベートにし、必要に応じてクラスのインスタンスを作成する 1 つの静的パブリック関数を提供するシングルトン クラスの例です。

私の質問は、new演算子を呼び出して静的関数内にシングルトン クラスのオブジェクトを作成すると、クラスのコンストラクターが確実に呼び出されるということです。私が知る限り、静的関数はクラスの静的メンバーと静的関数にしかアクセスできないため、それがどのように起こるか混乱しています。では、クラスのプライベート関数 (コンストラクター) にアクセスするにはどうすればよいでしょうか?

静的関数は、インスタンスを作成せずに、クラスのプライベートまたはパブリック メンバー関数を呼び出すことができますか?

#include <iostream>

using namespace std;

class Singleton
{
public:
    static Singleton *getInstance(); 

private:
    Singleton(){}
    static Singleton* instance;
};

Singleton* Singleton::instance = 0;
Singleton* Singleton::getInstance() 
{
    if(!instance) {
        instance = new Singleton(); //private ctor will be called
        cout << "getInstance(): First instance\n";
        return instance;
    }
    else {
        cout << "getInstance(): previous instance\n";
        return instance;
    }
}

int main()
{
    Singleton *s1 = Singleton::getInstance();
    Singleton *s2 = Singleton::getInstance();
    return 0;
}

しかし、以下のようにサンプルコードを書いたとき:

class Sample
{
    private:
        void testFunc()
        {
            std::cout << "Inside private function" <<std::endl;
        }
    public:
        static void statFunc()
        {
            std::cout << "Inside static function" <<std::endl;
            testFunc();
        }
};

int main()
{
    Sample::statFunc();

    return 0;
}

g++ でコンパイル エラーが発生します。

file.cpp: In static member function ‘static void Sample::statFunc()’:
file.cpp:61: error: cannot call member function ‘void Sample::testFunc()’ without object. 

静的パブリック関数を使用してクラスのプライベート関数にアクセスできる場合、なぜこのエラーが発生するのですか?

4

3 に答える 3

1

静的関数は、インスタンスを作成せずに、クラスのプライベートまたはパブリック メンバー関数を呼び出すことができますか?

インスタンスを作成しています。

instance = new Singleton();

newキーワードはオブジェクトを作成しますSingleton

そして、はい、Singleton::getInstanceクラスのメンバー関数であるため、コンストラクターを呼び出す機能があります (間接的にしか呼び出していないことに注意してください) static

于 2016-11-21T13:57:16.213 に答える
1

上記のコードが機能する理由は、 の実装がgetInstance()オブジェクトのインスタンスを必要としないコンストラクターを呼び出すためです。

静的メンバー関数は、オブジェクトではなくクラスに属します。したがって、静的メンバー関数を呼び出すときにオブジェクトのインスタンスはありません。ポインターがないため、thisポインターにアクセスできません。静的関数から非静的プライベート メンバー関数にアクセスする場合は、オブジェクトの参照を関数に渡す必要があります。例えば

例えば

class foo {
    public:
          foo(int i) : myInt(i) {}
          static int myStaticMethod(foo & obj);
    private:
          int myInt;
    };

    int foo::myStaticMethod(foo & obj) {
          return obj.myInt;
    }

#include <iostream>


int main() {
foo f(1);
std::cout << foo::myStaticMethod(f);
return 0;
};
于 2016-11-21T14:30:58.353 に答える
0

後で追加した質問の 2 番目の部分に対する回答:

class Sample
{
private:
  void testFunc()
  {
    std::cout << "Inside private function" << std::endl;
  }
public:
  static void statFunc()
  {
    std::cout << "Inside static function" << std::endl;

    Sample s;
    s.testFunc();          // this is OK, there is an object (s) and we call 
                           // testFunc upon s

    // testFunc();         // this is not OK, there is no object
  }
  void InstanceFunction()
  {
    std::cout << "Inside public instance function" << std::endl;
    testFunc();
  }
};


int main()
{
  Sample s;
  s.InstanceFunction();

  Sample::statFunc();
  return 0;
}

testFunc();内部からの呼び出しはstatFunc実行できません。(プライベートであろうとなかろうと) はインスタンス関数であるため、操作できるオブジェクトtestFuncが必要ですが、関数であるため、オブジェクトはありません。SampletestFuncstatFuncstaticSample

エラーメッセージはそれについてかなり明確です。

オブジェクトを提供する場合にのみtestFuncfromを呼び出すことができます。上記のコードを参照してください。statFunc

于 2016-11-21T14:16:18.517 に答える