2013-07-25 4 views
0

Я хочу достичь «этой строки» в следующем коде. Самый логичный способ - установить GetDog static, но тогда я не могу использовать «это». Есть ли способ обойти это? (Нет, так как я пытался это, там несколько строк, не имеющие отношения к вопросу)Функция вызова без объявления класса

#include <iostream> 

class Dog 
{ 
public: 
    static int a; 
    Dog& GetDog(int k) 
    { 
     this->a = k; 
     return *this; 
    } 
    int bark() 
    { 
     return a*a; 
    } 
}; 

int Dog::a=0; 

int main() 
{ 
    Dog puppy; 
    int i = puppy.GetDog(4).bark(); 
    cout<<i<<endl; 
    cout<<Dog::a<<endl; 
    //i = Dog::GetDog(6).bark();     //this line 
    return 0; 
} 

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

class EXOFastFourierTransformFFTW 
{ 
    public: 
    static EXOFastFourierTransformFFTW& GetFFT(size_t length); 
    virtual void PerformFFT(const EXODoubleWaveform& aWaveform, EXOWaveformFT& aWaveformFT); 
... 
int main() 
{ 
    EXODoubleWaveform doublewf; 
    EXOWaveformFT wfFT; 
    ... 
    EXOFastFourierTransformFFTW::GetFFT(doublewf.GetLength()).PerformFFT(doublewf,wfFT); 
... 

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

От голосования вниз, прежде чем я вижу, что это, вероятно, не обычный метод, как я думал. Прокомментируйте это, прежде чем делать это.

+2

Ваше название говорит C (почему), но помечено это C++ и использовать C++. – chris

+0

Что означает 'C:' означает в вашей функции название –

+0

Что именно вы спрашиваете? Какой класс, по вашему мнению, не объявлен? 'EXOFastFourierTransformFFTW' является объявленным классом в предоставленном коде, но не является классом _instantiated_. Во время выполнения нет объектов типа 'EXOFastFourierTransformFFTW', и это прекрасно, потому что вам не нужен объект этого типа для вызова статической функции' GetFFT'. Это все проверяет, но часть, которая меня интересует, заключается в том, что вызывающий код игнорирует возвращенный 'EXOFastFourierTransformFFTW &' из 'GetFFT'. Игнорирование возвращенной ссылки - плохое mojo .... – Shaz

ответ

0

Кажется, что это реализация Meyers singleton.

Объясняет:

В приведенном примере, класс EXOFastFourierTransformFFTW не кажется, есть конструктор, но возвращает ссылку на объект EXOFastFourierTransformFFTW.

И это выглядит следующим образом: осуществление

class Singleton 
{ 
public: 
    static Singleton& Instance() 
    { 
     static Singleton obj; 
     return obj; 
    } 

private: 
    Singleton(); 
}; 

От this book from Andrei Alexandrescu, он сказал:

Этот простой и элегантный реализация была впервые опубликована Скотт Мейерс; поэтому мы будем называть его как Meyers Singleton.

Meyers singleton полагается на некоторую магию компилятора. Объект-статический объект инициализируется, когда поток управления сначала передает свое определение. Не путайте статические переменные, которые инициализируются во время выполнения [...]

[...]

Кроме того, компилятор генерирует код таким образом, что после инициализации, поддержка выполнения регистрирует переменную для уничтожения.

Так хорошо использовать статический вызов метода из класса не реализованным, но не делайте этого, если не надо ... Вот представлять Singleton Pattern вы должны. Но теперь, если вы хотите, чтобы ваш класс Dog выглядеть

:

class Dog 
{ 
public: 
    static Dog& GetDog(int k) 
    { 
     static Dog obj(k); 
     return obj; 
    } 
    int bark() 
    { 
     return a*a; 
    } 
private: 
    int a; 
    Dog(int iA) : a(iA) {} 
}; 
+0

Это немного сложнее, поскольку функции 'Get' имеют параметры. Я бы не хотел, чтобы 'GetDog (1)' и 'GetDog (2)' ссылались на один и тот же объект ... – aschepler

+0

@aschepler Если вы посмотрите на этот пример, найденный в Интернете (https: //gist.github. com/mgmarino/3816940), я все еще думаю, что 'EXOFastFourierTransformFFTW' является синглом (по крайней мере, это похоже ...). Передача аргумента «GetFFT» - не очень хорошая идея, даже плохая идея для понимания, но ... –

+0

Мне кажется, что ссылка удалена после PerformFFT, но я не уверен, что это возможно. – Rabbitybunny

0

Правильное использование функции static - позволяет использовать функции из классов без экземпляра класса. Выбранный вами вариант FFT, вероятно, создает экземпляр внутри статической функции. Поэтому в вашем случае вы должны создать экземпляр Dog в функции GetDog (просто будьте осторожны с возвратом ссылок на локальные переменные!).

+0

Если статическая функция создала экземпляр, возвращение по ссылке, вероятно, было бы плохой ... –

+0

Вот почему я упомянул о том, чтобы быть осторожным с возвращающимися ссылками - если вы создавали экземпляр через 'new', я думаю, вы могли бы с ним справиться –

+0

Действительно , но потом кто его удалит и когда? 'T & t = T :: getT (42); ...; delete & t; 'не нравится код ... –

0

Вы говорите, что вы не можете использовать this, если вы это сделаете static, что верно. Но почему вы хотите получить к нему доступ, не используя экземпляр объекта, если вам понадобится использовать this в какой-то момент в будущем? Если у него есть значение по умолчанию или что-то в этом роде, вы можете объявить, что в другом месте за пределами функции, как public static, а затем получить доступ к нему таким образом. Если вы поясните немного больше о том, что делаете, я отредактирую/удалю этот ответ соответственно.

+0

Я думаю, что дело в том, что «писатель кода» не хочет, чтобы слишком много объявленных классов («экземпляр», я полагаю) в основном, если такой класс работает точно так же, как глобальная функция. И поскольку FFTW поступает из внешнего пакета, «public static» может быть не идеальным. (Я вроде думаю, что они, вероятно, могут использовать пространство имен, но я не знаком с этим) – Rabbitybunny

+0

@Rabbitybunny Пространства имен тоже будут работать. Я не эксперт по C/C++, но я думал, что брошу свои два цента в том, что будет работать. –

+0

Да, но пакет функций FFTW «достигнут» без использования пространства имен, а также глобального статического. Следовательно, я пытаюсь выяснить «эту» проблему внутри функции. Я попытался объявить переменную класса Dog в функции, но не смог ее обработать. – Rabbitybunny

Смежные вопросы