Cannot access object declared in constructor of class

From Visual Basic to GNU C, this is the place to talk programming.

Moderators: SecretSquirrel, just brew it!

Cannot access object declared in constructor of class

Postposted on Sat Apr 02, 2011 4:46 pm

So I have this class, CochlearImplantExperiment_amt. Within the constructor of this class I make an object of class QPainter called drawstuff, and drawstuff operates on a QPixmap, called pixmap. This is all within the constructor so far, and are listed under protected: in the header files.

Now I make a function within CochlearImplantExperiment_amt. This function is a public slot, and is called void doimplantscomeinellipses(). All this function does is make drawstuff->drawEllipse(100,100,250,100) whenever a button is clicked. But for some reason it always generates a runtime error. I cut and paste the drawEllipse line into the constructor, and sure enough the ellipse is painted.

As far as I know, anything that's declared/used in the class should be able to access one another. Why does it then give a runtime error? Probably because that isn't the case. But I would really really like to avoid making a QPixmap, making a QLabel to display said pixmap, and making a QPainter all within each function that is meant to simply draw a particular shape on the screen.

What's wrong here? I've included some snippets of code, first up is the header file:
Code: Select all
public slots:
   void nameInputChanged( const QString & );
   void distanceModeChosen(const QString & string);
   void operationModeChosen(const QString & string);
   void modeClicked(int id);
   void startStopClicked();
   void doimplantscomeinellipses();
protected:
   QWidget* _guiTab;

   QLabel* _nameLabel;
   QLabel* _testLabel;

   //DisplayWidget_amt*  _displayWidget;

   CameraInterface_amt* _cam;

   QLineEdit* _nameInput;

   QComboBox* _frequencyBox;
   QPixmap *pixmap;
   QLabel *pixmaplabel;
   QPainter *drawstuff;
   QPushButton* _startStopButton;
   QPushButton *ellipse;
   QPointArray splineone;
   QString* _subjectName;

Code: Select all
void CochlearImplantExperiment_amt::doimplantscomeinellipses()
{
   drawstuff->drawEllipse(100,100,200,150);
}

In the constructor:
Code: Select all
   QPushButton *ellipse = new QPushButton("&Ellipse", modeFrame);
   ellipse->setGeometry(10,160,100,40);
   connect(ellipse,SIGNAL(clicked()),this,SLOT(doimplantscomeinellipses()));
   
   QLabel *pixmaplabel = new QLabel(testFrame);
   pixmap = new QPixmap(650,600);
   pixmaplabel->setPixmap(*pixmap);
   pixmaplabel->setAutoResize(TRUE);
   QPainter *drawstuff = new QPainter(pixmap);
   QPointArray splineone(4);
   splineone[0]=QPoint(50,50);
   splineone[1]=QPoint(150,0);
   splineone[2]=QPoint(150,150);
   splineone[3]=QPoint(400,200);
   drawstuff->setPen(Qt::red);
   drawstuff->drawRect(10,10,200,100);
   drawstuff->drawCubicBezier(splineone);
   drawstuff->drawRoundRect(200,180,400,320);
   _nameInput = new QLineEdit(modeFrame);
   _nameInput->setGeometry(10,50,280,45);
   connect(_nameInput,SIGNAL(textChanged ( const QString & )),this,SLOT(nameInputChanged( const QString & )));
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
Crayon Shin Chan
Minister of Gerbil Affairs
 
Posts: 2251
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia

Re: Cannot access object declared in constructor of class

Postposted on Sat Apr 02, 2011 5:28 pm

You appear to be re-declaring a bunch of the protected members as local variables within the constructor. This would result in the protected members never getting initialized.
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 38086
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: Cannot access object declared in constructor of class

Postposted on Sun Apr 03, 2011 12:16 am

Actually when I started work on this program, it always was like this. I guess it was a policy of the original programmer's? I don't really see the problem...
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
Crayon Shin Chan
Minister of Gerbil Affairs
 
Posts: 2251
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia

Re: Cannot access object declared in constructor of class

Postposted on Sun Apr 03, 2011 4:31 am

Crayon Shin Chan wrote:Actually when I started work on this program, it always was like this. I guess it was a policy of the original programmer's? I don't really see the problem...

Actually JBI was pretty spot on. You have member variables like "drawstuff" declared in the header, but in the constructor, you have statements like these:
Code: Select all
QPainter *drawstuff = new QPainter(pixmap);

In the above you are actually declaring and initializing a stack variable, also called "drawstuff". Removing QPainter* would allow the compiler to know that you meant the member variable, not the local one.

Your compiler should have warned you about this, as it is very common to have the same names and you will be hiding the member variable. Actually it is pretty bad form to have member variables and local variables named the same. Hence there are schemes like Hungarian notation (m_ prefix for member vars) and the underscore (_ prefix) to more clearly indicate member variables. Of course, grammatically there is nothing stopping you from doing it. However, you are confusing the compiler and anybody who reads this code, including yourself (may be at a later time). Unreadable code is unmaintainable code, not that you cannot have correct logic but it is not helping.

Edit:
Initialization of pixmap seemed correct though:
Code: Select all
pixmap = new QPixmap(650,600);
Image
The Model M is not for the faint of heart. You either like them or hate them.

Gerbils unite! Fold for UnitedGerbilNation, team 2630.
Flying Fox
Gerbil God
 
Posts: 24578
Joined: Mon May 24, 2004 2:19 am

Re: Cannot access object declared in constructor of class

Postposted on Sun Apr 03, 2011 7:05 am

I think I get it now. Thanks for all your help!
EDIT: VS2003 didn't warn about this.
Mothership: Thuban 1055T@3.7GHz, 12GB DDR3, M5A99X EVO, GTX470+Icy Vision Rev.2@840/3800, Vertex 2E 60GB
Supply ship: Sargas@2.8GHz, 12GB DDR3, M4A88TD-V EVO/USB3
Corsair: Macbook Air Ivy Bridge
Crayon Shin Chan
Minister of Gerbil Affairs
 
Posts: 2251
Joined: Fri Sep 06, 2002 11:14 am
Location: Malaysia

Re: Cannot access object declared in constructor of class

Postposted on Sun Apr 03, 2011 12:15 pm

Crayon Shin Chan wrote:EDIT: VS2003 didn't warn about this.

Hmm I may be confused with C#. It warned me recently I think. :oops:

Anyway, something that you definitely need to look out for. In a way you are lucky that you are getting a runtime error right away since you are dealing with pointers. If it were something say an integer or boolean flag, you will not get a crash right away and you may be scratching your head wondering why your code does not work. Even under the debugger you may be looking at the watch window and wonder why the value of the variable(s) is not what you are expecting.
Image
The Model M is not for the faint of heart. You either like them or hate them.

Gerbils unite! Fold for UnitedGerbilNation, team 2630.
Flying Fox
Gerbil God
 
Posts: 24578
Joined: Mon May 24, 2004 2:19 am

Re: Cannot access object declared in constructor of class

Postposted on Sun Apr 03, 2011 12:32 pm

Crayon Shin Chan wrote:Actually when I started work on this program, it always was like this. I guess it was a policy of the original programmer's? I don't really see the problem...

If it was a policy of the original programmers to code like this, then the code they wrote is full of bugs.

Just to elaborate a bit more... the member variables are never getting initialized because you're assigning the new objects to local pointers within the constructor; these get thrown away when the constructor returns. So when you subsequently try to use the member variables from a different member function, they are still uninitialized. You're trying to execute a member function of an object instance that doesn't exist (hence the exceptions).

This will also result in memory leaks, since the objects you are allocating via new in the constructor are never getting deleted; the pointer to the object simply falls out of scope at the end of the constructor. Unlike some other languages, C++ does not do automatic garbage collection; so the memory occupied by those "orphaned" objects will not be reclaimed until the application exits.
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 38086
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: Cannot access object declared in constructor of class

Postposted on Sun Apr 03, 2011 12:41 pm

just brew it! wrote:
Crayon Shin Chan wrote:Actually when I started work on this program, it always was like this. I guess it was a policy of the original programmer's? I don't really see the problem...

If it was a policy of the original programmers to code like this, then the code they wrote is full of bugs.

Just to elaborate a bit more... the member variables are never getting initialized because you're assigning the new objects to local pointers within the constructor; these get thrown away when the constructor returns. So when you subsequently try to use the member variables from a different member function, they are still uninitialized. You're trying to execute a member function of an object instance that doesn't exist (hence the exceptions).

This will also result in memory leaks, since the objects you are allocating via new in the constructor are never getting deleted; the pointer to the object simply falls out of scope at the end of the constructor. Unlike some other languages, C++ does not do automatic garbage collection; so the memory occupied by those "orphaned" objects will not be reclaimed until the application exits.

I doubt it is the policy. If you look at the class declaration again the first few member variables use the _member convention. May be someone else started violating the coding style, or those other ones without the underscore was done by the OP without understanding the coding style. I normally don't care too much about coding style (especially that one about writing an essay on each and every function, which is guaranteed to be out of date the moment the code is worked on at a different time) but this one is quite useful.
Image
The Model M is not for the faint of heart. You either like them or hate them.

Gerbils unite! Fold for UnitedGerbilNation, team 2630.
Flying Fox
Gerbil God
 
Posts: 24578
Joined: Mon May 24, 2004 2:19 am


Return to Developer's Den

Who is online

Users browsing this forum: No registered users and 1 guest