PDA

View Full Version : Problems accessing static member variable from static member function



montylee
7th October 2008, 13:40
I have a class with a static variable of type QComboBox *. I have created a static member function from which i want to return this static variable. Here is the sample code:

Header code

Class TestPage : public QWidget
{
---
---
---
public:
static QComboBox *getTestCombo ();

private:
static QComboBox *sm_pTestCombo;
};

CPP code

QComboBox * TestPage::getTestCombo ()
{
return sm_pTestCombo;
}


I am getting the following linking error:

undefined reference to 'TestPage::sm_pTestCombo'


Any ideas?

spirit
7th October 2008, 13:51
you must init static variable


QComboBox *Test::m_comboBox = new QComboBox();


why do you need this method of storing/getting of QComboBox?

montylee
7th October 2008, 14:00
got it working...
searched the internet and found that i have to define the static member variable again in the CPP file at file scope.

So i have added this on top of the CPP file:

QComboBox* TestPage::sm_pTestCombo;

But that brings me to a questions that is it worth it?
Now the static variable can be accessed by anyone using the scope resolution operator. Same thing can be done by simply using a global variable in the CPP file, so just take a global variable in the CPP file and be happy. Why should i use the static variable then?

montylee
7th October 2008, 14:04
you must init static variable


QComboBox *Test::m_comboBox = new QComboBox();


why do you need this method of storing/getting of QComboBox?
i already got my solution... i have posted it...

I need to get the combo box pointer as i need to add items to it from a different class.

If i use a normal member function to return the combo box pointer it won't work as as i have to first create an instance of this class in the other class to invoke the member function. As soon as i create an instance, the member combo box variable is allocated a new memory and i am not able to get the original combo box pointer.

So , i have to call it directly without using an object, so i have to use either statiic or a global variable...

pls read my earlier post and suggest if i should go for global or static member variable.

spirit
7th October 2008, 14:05
this variable is private, you can't get access from another class.

montylee
7th October 2008, 14:06
i have made it public and my code is working. But i am not sure whether to use static member variable or use a global variable...
both approaches r working...

pls suggest which one is better.

spirit
7th October 2008, 14:08
I suggest you to add method in you class which will add item to a combobox and refuse using of global pointer to the combobox or using static variable.

montylee
7th October 2008, 14:18
I suggest you to add method in you class which will add item to a combobox and refuse using of global pointer to the combobox or using static variable.

The problem is:

Suppose the combo box is part of class A:

class A {
private:
QComboBox *m_pTestCombo;

public:
void updateCombo ();
}

Now, suppose i want to update the combo box from a different class B. For that, i have to call updateCombo () function of class A from class B.
For calling the updateCombo () function of class A, i have to first create an object of class A in class B. For e.g.


void B::someFunction ()
{
A obj;
obj.updateCombo;
}

Now, as soon as i create a new object of class A in class B, calling updateCombo function will have no effect on the GUI because when i create a new object of class A, new memory is allocated to m_pTestCombo variable. So, even if the code to add items is executed this way, i am unable to see the updated combo box in the GUI as the GUI is still showing the original combo box.

So, basically i have to get the same instance of the combo box which is being displayed on the GUI. Getting the existing instance of the pointer is only possible if i use a static member variable and call the updateCombo () function without creating a new object.
I hope i have explained my problem well...

spirit
7th October 2008, 14:21
you must provide interface in a class which keep combobox to setting/getting information, but don't allow to use members of this class to another classes. this is bad idea.

spirit
7th October 2008, 14:24
in you case, I suggest you add method to a class, which updates combobox, which will return QStringList with new items, and in a class, which keeps combox, method which will set new items (QStringList).

montylee
7th October 2008, 14:27
ok, i got a bit confused with my own code. Here's what i am doing now:

Header code:

Class TestPage : public QWidget
{
---
---
---
public:
static QComboBox *getTestCombo ();

private:
static QComboBox *sm_pTestCombo;
};

CPP code


QComboBox* TestPage::sm_pTestCombo;
QComboBox * TestPage::getTestCombo ()
{
return sm_pTestCombo;
}

Now, sm_pTestCombo is a private variable so it can't be accessed from the other class directly.

From the other class, i am calling getTestCombo() to get the combo box pointer.


QComboBox *testCombo = TestPage::getTestComboBox ();


Does this approach look ok? The member variable is now private and other classes have to use the public member function to get the variable's address.

spirit
7th October 2008, 14:31
this looks ok, but when you define QComboBox like static class member you didn't set a parent. so when you start application you will see this combobox like separate widget. so, you must reparent combobox in this case. anyway, I suggest you refuse this approach. :)

montylee
7th October 2008, 14:38
this looks ok, but when you define QComboBox like static class member you didn't set a parent. so when you start application you will see this combobox like separate widget. so, you must reparent combobox in this case. anyway, I suggest you refuse this approach. :)

no, my code is working fine. I have a separate combo box member variable which is actually displayed on the GUI. The static variable is just used as i require to pass the address of the variable to a different class through a static function. Since a static member function can only access static member variables, so i had to use an extra variable...

in the class constructor, i just assign the normal combo box pointer to the static combo box variable...in the GUI, the normal combo box is displayed.

spirit
7th October 2008, 14:40
I guess it works fine, because you use layouts.

montylee
7th October 2008, 14:43
yes i am using layouts but as i said the combo box being shown on the GUI is a normal member variable.
The static variable just stores the same address as the normal variable...so it's just a copy...

Thanks for your help!

spirit
7th October 2008, 14:43
in the class constructor, i just assign the normal combo box pointer to the static combo box variable....
this can lead to memory leak, because when you init static variable you create a new comboboex and then (according to your words) you reset variable with a new object, but don't destroy old.

montylee
7th October 2008, 14:48
i am not allocating new memory for the static combo box, i am just assigning the same address to the static variable, so there is no extra memory allocation. Here's my code:


sm_pTestCombo = m_pTestCombo;

here, sm_pTestCombo is the static member variable and m_pTestCombo is the normal member variable.

spirit
7th October 2008, 14:50
what about this


QComboBox *Test::m_comboBox = new QComboBox();

?

spirit
7th October 2008, 14:52
if you use code like this


QComboBox *Test::m_comboBox = 0;

then ok.

montylee
7th October 2008, 14:53
i think that code was posted by you. I am not allocating any new memory :)

Sandip
8th October 2008, 14:43
Hi,

You can try a different solution.
Let's see it is easy and safe also.

class GetComboInstance
{
public:
static GetComboInstance* createInstance();
updateCombo();
private:
QComboBox *m_pComboBox;
static GetComboInstance *m_pInstance;
};

In Cpp file:

static GetComboInstance *GetComboInstance::m_pInstance = NULL;
static GetComboInstance* GetComboInstance::createInstance()
{
if(m_pInstance == NULL)
{
m_pInstance = new GetComboInstance();
}
return m_pInstance;
}

now you can call updateCombo method on your instance of GetComboInstance class from any class. It is better and safe way.

Sandip
8th October 2008, 14:46
Please let me know what do you think

Kumosan
8th October 2008, 14:54
I think that when you describe the singleton pattern, you should do it right, e.g. make constructors protected or private. ;-)

http://www.inquiry.com/techtips/cpp_pro/10min/10min0200.asp