-
global class pointers
Hey all I have a problem... and I have just about exhausted my avenues... now I have searched but haven't found anything which adequately answers my question, and have done a lot of research on it, but no luck so far.
So... I turn to you the community for help.
So my problem sounds simple enough, I am using MFC.
I have a dialog which I want to basically popup and minimize the main view until it is fully connected to something. I.E. when it connects to the server it should just display a modal dialog and wait, continually updating messages until it completes, then it minimizes itself and is no longer used.
Relevant code
file globals.h
Code:
class CtesterView; ///supposedly a forward definition
extern CtesterView * ct;
file StatusMonitor.h
Code:
#pragma once
#include <winsock.h>
#include "globals.h"
// StatusMonitor dialog
class StatusMonitor : public CDialog
{
DECLARE_DYNAMIC(StatusMonitor)
public:
StatusMonitor(CWnd* pParent = NULL); // standard constructor
virtual ~StatusMonitor();
void setPtr();
void mess();
// Dialog Data
enum { IDD = IDD_CONNECT };
CtesterView * myct;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
};
file StatusMonitor.cpp
Code:
#include "stdafx.h"
#include "tester.h"
#include "StatusMonitor.h"
// StatusMonitor dialog
IMPLEMENT_DYNAMIC(StatusMonitor, CDialog)
StatusMonitor::StatusMonitor(CWnd* pParent /*=NULL*/)
: CDialog(StatusMonitor::IDD, pParent)
{
}
StatusMonitor::~StatusMonitor()
{
}
void StatusMonitor::mess()
{
myct->msg();
}
void StatusMonitor::setPtr()
{ myct = ct; }
void StatusMonitor::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(StatusMonitor, CDialog)
END_MESSAGE_MAP()
// StatusMonitor message handlers
as you can see its just mostly generated code via msvc .net 2003...
basically how can I make it so I can pass the pointer from CtesterView (the generated view class) to my dialog class (StatusMessage) and allow it to call certain functions?
Or is there a better way to implement it? I could only think of global pointers... and everytime I try to use them, msvc tells me that in StatusMonitor.cpp the CtesterView is undefined. Or am I just missing something glaringly obvious? Any help would be appreciated, thanks.
-
any ideas? or is this just a dumb question? I can't seem to figure it out, so I thought I'd ask here, it sounds easy enough, but whatever I do does not seem to help.
-
Hello,
When using extern to see global variables, it is sometimes common to create the variable in the .cpp file and the extern link in the .h file.
For example:
StatusMonitor.cpp:StatusMonitor.h:
Code:
// Define/Make class
...
// Extern it afterwards
extern CtesterView *ct;
This tells your compiler that in the *.cpp file that you are declaring a variable, while in your *.h file this variable is an external variable which any other file that includes this header will get access to that variable and its data.
So if you had Test.cpp for example and if you included "StatusMonitor.h", your new *.cpp file should be able to access your class variable of ct, and all of its members.
Note: You can extern your variable in globals.h and/or StatusMonitor.h; which either of them best suits your project.
Lastly, an extern variable has global storage and external name space. This is the default storage class for functions. Used inside of a function, extern specifies that the storage for the declared object is defined somewhere else. If the existence of a global variable in one file is declared using the extern keyword in another file, the data is available for use by the second file.
- Stack Overflow
-
nevermind I figured it out, some weird way, but I did get it figured out, basically just had to include the cpp file in the dialog class for some reason... but it works now.
-
hmm so what you are saying basically is to define CtesterView * ct; in the .cpp file (this is the SDI view for MFC btw) and then call extern CtesterView * ct; after I define the class StatusMonitor?
-
Well I am simply saying that you can extern your classes variable in a header file and declare it in the .cpp file.
The thing is that you can't just extern a variable and expect to use it. Somewhere, in a *.c or *.cpp file you have to declare it into existance, if not you may get errors like "unresolved external symbol".
For example if you had a file called Main.h which looked like:Main.cpp:
Code:
#include "Main.h"
int main() {
a = 1;
return 0;
}
That would probably give you an error. If you declare a in the *.cpp file, the compiler will not give you an error.
Main.cpp:
Code:
#include "Main.h"
int a;
int main() {
a = 1;
return 0;
}
If you added another file to your project, say, Test.cpp and included Main.h you can modify and change a without declaring it there since the existence of our variable is in one file which was declared using the extern keyword in the *.h file. So in the other file [Test.cpp], the data is available for use.
Test.cpp:
Code:
#include "Main.h"
void foo(void) {
a = 5;
}
That's all I was really trying to explain.
- Stack Overflow
-
Oh, agreed.
Thanks, that helps a bit more, I am just wondering if there a nice quick and easy way to do this. From what I remmebered (without MFC) globalizing pointers was very easy, but with MFC I must be missing something is all. I understand what you are saying but currently I just want to know of a decent way to do this in practice. Any ideas would greatly help :)
additionally, when I write this code ...
Code:
extern CtestView * ct;
in globals.h
and
Code:
extern CtestView * ct = NULL;
in
the main test app (tester.cpp)
then I use it like
in my StatusMonitor.cpp
it tells me that I am using an undefined type of CtestView (which is forward defined in the globals and yet it tells me its not a valid type... I'm kinda lost on this.
-
Just by quickly looking over your code, you do not need to extern your variable in any *.cpp file, just the *.h once.
Rather than having:
Code:
extern CtestView * ct = NULL;
In your tester.cpp file, it should be more on the lines of:
Code:
CtestView * ct = NULL;
Also, be sure to include globals.h in your testers.cpp so you can use the externed variable. If you already declared the variable in another *.cpp file there is no need to do it in testers.cpp.
Extern once [*.h file]
Declare once [*.cpp file]
All other *.cpp files that include the *.h file should be able to modify and change the externed variable.
- Stack Overflow
-
hmm interesting, I did do that, but it makes me include the testerView.cpp file in, otherwise it complains that I am using an undefined type of type CtesterView(the class of course that I am trying to get a pointer to in the global.h file). Why should I include that? I would assume it already knows about that class... its being called from that class to begin with... why does it need the implementation again? Is there any reason it is like this? Any theories or ideas or "this is why it is" comments would help a lot, thanks.
-
Ah,
Sorry about that. I re-read your original post where globals.h was included in StatusMonitor.h, not the other way around. I meant to put your extern variable in the most common header file, which in this case would be StatusMonitor.h
So any file that includes that header file can use the externed variable if previously declared. What I mean by this is:
Extern [in a *.h]:
Code:
extern CtestView * ct;
Declare [in a *.cpp (only in one, and only once)]:
Code:
CtestView * ct = NULL;
If you have further questions, please feel free to ask.
- Stack Overflow
-
I must have terrible luck :)
error C2027: use of undefined type 'CtesterView'
error C2227: left of '->msg' must point to class/struct/union
the line this happens on:
this is in StatusMonitor... if I include the testerView.cpp file, I get tons of errors which tell me that the functions in testerView already exist, which makes sense, since StatusMonitor.h is included in testerView already, and I am making the call to a new StatusMonitor from testerView.
since I am using a
Code:
statusmonitor->create(//ID of my dialog, this);
is there a way I could get the pointer to the class from that?
Since I apparently cant get it to realize that I have forward declared my class(before I use the class), and that the class is defined and calls the creation of the Dialog.