2015-05-20 3 views
1

Я разбил свой вопрос на небольшую простую программу.Статические функции и переменные класса?

У меня есть класс myclass Я создал в отдельном файле .cpp «classes.cpp» и объявлен в файле заголовка «classes.h». myclass содержит переменную a, из которой инициализируется при создании экземпляра. Это делает переменную a = 5.

Моя общая цель - создать класс в отдельном файле .cpp, объявленном в файле .h, который я могу создать несколько экземпляров в моей программе main(). Проблема, с которой я столкнулась, заключается в следующем.

В моей функции main() я создаю экземпляр myclass под названием first. Моя основная программа показывает, что переменная a установлена ​​на номер 5. Если я хочу изменить это число, используя статическую функцию (и она должна быть статической функцией, поскольку это относится к чему-то значительно большему в другой программе, которую я пишу) , Я вызываю статическую функцию напрямую и в этой static_function создаю экземпляр myclass и вызываю функцию non_static_function, потому что статические функции не подразумевают «это», соединяющие их с объектом.

В моей функции non_static_function я изменяю значение на число 8. Проблема в том, что значение переменной 'a' в 'first' остается в 5, когда я хочу, чтобы оно было 8. Мне нужно изменить значение, используя first->static_function(8), а неfirst->a = 8. , Как я могу это сделать?

код ниже:

**main.cpp** 
#include <iostream> 
#include "classes.h" 

using namespace std; 

int main() 
{ 

    myclass *first = new myclass(); 
    cout << "Myclass variable a is = " << first->a << endl; 

    first->static_function(8); // trying to change myclass variable 'a' to 8. 

    cout << "But" << endl; 
    cout << "the actual value of a is still: " << first->a << endl; 
} 

**classes.h** 
#ifndef CLASSES_H_INCLUDED 
#define CLASSES_H_INCLUDED 
class myclass 
{ 
public: 
    int a; 
    myclass(); 

    void non_static_function(int x); 
    static void static_function(int x); 

}; 
#endif // CLASSES_H_INCLUDED 

**classes.cpp** 
#include <iostream> 
#include <cstdlib> 
#include "classes.h" 

using namespace std; 

myclass::myclass() 
{ 
    a = 5; 
} 

void myclass::non_static_function(int x) 
{ 
    a = x; 
    cout << "The value for variable 'a' was 5 but is now: " << a << endl; 
} 

void myclass::static_function(int x) 
{ 
    myclass *p = new myclass(); 
    p->non_static_function(x); 
} 
+0

Невозможно изменить нестатическое поле со статическим методом, если вы не передадите экземпляр ('first'), который вы хотите изменить. – Carcigenicate

+0

Вот почему вы создаете экземпляр этого объекта в своей статической функции и вызываете функцию non_static. Насколько я знаю, функция non_static_function должна иметь возможность изменить значение класса (и я не уверен, почему он не будет отражать в первом экземпляре. – Svetsi

+1

'p' в' static_function' сразу же выходит из области видимости в конце функции, поэтому ничего не повлияет. Имейте в виду, что 'p', созданный в' static_function', полностью отделен от любого другого созданного вами экземпляра, например 'first'. Изменение «p» на 0 будет иметь значение «first». Будьте осторожны, используя 'new', вы не должны использовать его, как и вы. Вы никогда не вызываете delete на нем, поэтому он никогда не освободит запрашиваемое пространство (что не происходит автоматически, как в java). Как правило, вы никогда не должны использовать 'new' вне конструктора. – Carcigenicate

ответ

2

Если вы хотите каждый экземпляр myclass иметь свой собственный a и вы хотите вызвать статическую функцию, чтобы изменить его, то вам нужно передать экземпляр вы хотите изменить на статический функция. Статическая функция может изменять только статические члены класса или члены экземпляра, находящегося внутри его области. Нестационарные функции-члены могут изменять любую переменную, являющуюся членом класса.

class Foo 
{ 
private: 
    int bar; 
public: 
    static void static_function(int value, Foo & foo) { foo.bar = value; } 
    void non_static_function(int value) { bar = value; } 
}; 

int main() 
{ 
    Foo foo; 
    Foo::static_function(8, foo); 
    // now bar will have the value of 8 
    foo.non_static_function(20); 
    // now bar will have the value of 20 
} 
+0

, пожалуйста, не создавайте * статическую * функцию, а затем передавайте экземпляр ... –

+0

Кажется, что он сам '' сам статичен; хотя я не уверен, что это лучший выбор дизайна. – Carcigenicate

+0

@KarolyHorvath Я согласен с тем, что OP не должен этого делать, но я хотел продемонстрировать, как они могут, если им это нужно. – NathanOliver

0

Я, наконец, нашел способ справиться с этой небольшой проблемой. Над определением «myclass» в classes.cpp объявляю переменную «myclass» myclass * tgt;. Затем в моем конструкторе для «myclass» я просто выделил экземпляр объекта для моей глобальной переменной myclass, из которой я могу получить доступ из определения myclass tgt = this; Теперь я могу использовать tgt в своей статической функции, чтобы вызвать функцию non_static_function в моем определении myclass, и все это работает отлично.

NathanOliver, вы правильно говорите, что мне нужен экземпляр класса, но способ, которым я это сделал, подходит мне. Передача экземпляра myclass - это, конечно, еще один способ сделать это, но для определения класса myclass потребуется глобальная функция.

Спасибо за помощь.

**main.cpp** 
    #include <iostream> 
    #include "classes.h" 

    using namespace std; 

    int main() 
    { 

     myclass *first = new myclass(); 
cout << "Myclass variable a is = " << first->a << endl; 

first->non_static_function(8); // trying to change myclass variable 'a' to 8. 

cout << "But" << endl; 
cout << "The actual value of a is still: " << first->a << endl; 

myclass *second = new myclass(); 
cout << "For the 'second' class the variable a is: " << second->a << endl; 
second->non_static_function(23); 
cout << "After calling the static function from 'second' the value of a is: " << second->a << endl; 
cout << "And first->a is still: " << first->a << endl; 
    } 



    **classes.h** 
    #ifndef CLASSES_H_INCLUDED 
    #define CLASSES_H_INCLUDED 
    class myclass 
    { 
    public: 
     int a; 
     myclass(); 

     void non_static_function(int x); 
     static void static_function(int x); 

    }; 
    #endif // CLASSES_H_INCLUDED 





    **classes.cpp** 
    #include <iostream> 
    #include <cstdlib> 
    #include "classes.h" 

    using namespace std; 

    myclass *tgt; // *Add a global myclass variable above the myclass 
     definition* 

    myclass::myclass() 
    { 
     tgt = this; // *In the constructor allocate the instantiated class 
    //from main() to "tgt" .* 
     a = 5; 
    } 

    void myclass::non_static_function(int x) 
    { 
     a = x; 
    // Now see that the value of a is changed. 
    cout << "The value for variable 'a' was 5 but is now: "<< this->a << endl; 
    } 

    void myclass::static_function(int x) 
    { 
     tgt->non_static_function(x); 
    } 
+0

На самом деле, я признаю, что мое решение разрешает часть проблемы. Если я делаю несколько экземпляров myclass, функциональность обоих экземпляров сталкивается при определенных обстоятельствах. Поэтому мой вопрос развивается. Кто-нибудь знает, как отслеживать несколько экземпляров myclass, чтобы при доступе к каждому экземпляру изменения происходили только в классе, к которому я обращался? Я думаю статический счетчик, вектор или карту, но я не уверен. Должен быть стандартный способ сделать это? – Svetsi