2016-11-21 12 views
1

Я столкнулся с кодом, подобным приведенному ниже, который в основном является примером одноэлементного класса, в котором мы создаем конструктор класса private и предоставляем одну статическую публичную функцию для создания экземпляр класса при необходимости.Как статическая функция, получающая доступ к частной функции-члену (конструктору) класса

Мой вопрос в том, что мы вызываем оператор 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; 
} 

Я получаю ошибку компиляции с г ++:

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

Если мы можем получить доступ к собственной функции класса со статическими общественности функция, то почему я получаю эту ошибку?

+0

Короткий ответ: ИМХО да. И IMHO нет проблем с вашим кодом. 'getInstance' является членом класса Singleton, поэтому он может вызывать все методы класса, даже частные. –

ответ

0

Причина, по которой этот код работает, заключается в том, что реализация 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; 
}; 
+0

Спасибо за ваш ответ. Так что я понял из выше, так как ctor - это специальная функция-член, которая не требует вызова какого-либо объекта, поэтому ее можно вызывать с использованием статической функции (без какого-либо объекта), но другие нормальные функции-члены класса нуждаются в экземпляре класса в чтобы вызвать их, чтобы их нельзя было вызвать внутри статической функции без объекта. – Viki

+0

Да, в значительной степени – TomJ

1

Может ли статическая функция вызывать любую закрытую или публичную функцию-член класса без создания какого-либо экземпляра?

создание экземпляра.

instance = new Singleton(); 

new ключевое слово создает Singleton объект.

И, да, поскольку Singleton::getInstance является функцией-членом класса, он имеет возможность ссылаться на конструктор (хотя обратите внимание, что вы делаете это только косвенно), независимо от того, static или нет.

0

Ответ на вторую часть вашего вопроса, что вы добавили позже:

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; 
} 

Calling testFunc(); изнутри statFunc не может быть сделано, потому что testFunc (частный или нет) является функцией экземпляра, вам нужно Sample объект, который testFunc может работать, но statFunc - static функция, поэтому нет Sample объект.

Сообщение об ошибке довольно ясно об этом.

Вы можете позвонить по телефону testFunc с statFunc, только если вы предоставите объект, см. Код выше.

+0

Я думаю, что аналогичным образом контрмер одноэлементного класса является функцией класса и не должен вызываться статической функцией. Если конструктор может вызываться внутри статической функции, то почему бы не обычная личная функция, что меня смущает? – Viki

+0

@Vikram помните, что конструктор не является нормальным элементом funtion. Когда вы пишете 'instance = new Singleton();' you _are_, создаете объект, и конструктор вызывает объект, который создается. –

+0

@ Викрам, я отредактировал ответ, теперь есть пример того, как вы можете вызывать 'testFunc' из' statFunc'. –