variables

Hello i dont really know how to explain this but i have a variable called
string place;
and i got two .cpp files thaat are trying to use it how do i make it so they both are able to use it.
i got main.cpp and outcomes.cpp plus outcomes.h for my files
Last edited on
Are you talking about a global variable?
ya but i just dont know how to use one variable from the main.cpp and make it so it works in the outcomes.cpp
Here's one (and one of the better ways IMO) to do it.

Create a header file in your project (.h or .hpp) to act as a "bridge" between your two files. In the header, write:
extern std::string place;
The extern keyword is a keyword that lets the compiler know that a variable that's not explicitly declared in one file can be found in another, and prevents naming conflicts. If I were to just put down std::string place; without the extern, I'd get an error as #include is a copy-and-paste directive, and I'd have two separate but identically named variables in both files.

And then, include the newly created header file. I'll let you figure out how and where to do that one on your own. MAJOR HINT: You'll need to replace the < > with " ".

-Albatross
[Linker error] undefined reference to `Place'
thats what happens.....
closed account (3pj6b7Xj)
Be very carefull with global variables and only use them as a last resort. If your not carefull, your program can end up modifying stuff here and there and then debugging becomes a nightmare because you just don't know what is modifying what.

Here is my rule for global variables, I make globals that must be modified only to be used in the main program file, the main cpp. Files that need extern for example in a header, oh boy, I don't like modifying those, thats asking for trouble.

My rule for extern is....I can make a HWND g_hWnd; global and assign it the window handle or I can make a HDC g_WinDC; and assign the device-context of the window handle but there is no way in the world i'm modifying those variables from another part of the program, id be digging my own grave. It would be nice if you could make them const but that is not possible since you would have to declare the whole thing at once "const HDC g_WinDC = GetDC(hWnd);" since a global is declared before main, this would be impossible since I have not obtained the handle to the window....unless some how there is a way to make them const once they are declared, then that would be sweet for those variables I don't need to be messing around with.
Ok i just figured it out thanks working perfectly now :D i didnt declare the variable in my main.cpp thats it.

thanks for the input to mrfaosfx but im just trying to figure out how everything works gotta try everything and see what works for me
closed account (3pj6b7Xj)
You got me interested in this and realized this is a type of functionality I would love to have. In order to create a variable that can be declared but not initialized, it needs to have a mind of its own, so i just wrote this little class for starters...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class varlock
{
    public:
    varlock() { locked = false; }
    
    void set(int var_) { if (!locked) variableType.var = var_; locked = true; }
    void set(float var_) { if (!locked) variableType.var = var_; locked = true; }
    void set(string var_) { if (!locked) variableType.var = var_; locked = true; }
    void set(double var_) { if (!locked) variableType.var = var_; locked = true; }
    void set(char var_) { if (!locked) variableType.var = var_; locked = true; }
     
    private:
    union _vartype_
    {
        int var;
        float var;
        string var;
        double var;
        char var;
    } varType;
    
    protected:
    bool locked;
    varType variableType;
};


The idea behind this is, if I made an int...

1
2
varlock intVar; // variable declared... non const.
intVar.set(10); // variable declared and now lock, can no longer be modified! 


This was just experimenting but I can pretty much make a template out of this class that can substitute the type for the variable type I want to use.....templates are sweet things. I will look further into this, will probably spend a couple of hours on it.

Hopefully when its complete, I can create a variable of type HWND and once I store the window handle in it, it will be locked and can not be modified from any part in the program, specifically those headers using extern.

there may already be a simple way to do this but hey I am not aware of it.
so you can change it from a constant variable to constant and back and forth is that what your idea is?
closed account (3pj6b7Xj)
No, it should create a non-constant variable and then when you hand it a value it becomes constant, in theory. I just finished the template version and it works!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <class T>
class lockvar
{
    public:
    lockvar() { locked = false; }

    void set(T varType_)
    {
        if (!locked)
        {
            varType = varType_;
            locked = true;
        }
    }

    T get() { return varType; }

    protected:
    bool locked;
    T varType;
};


So if I wanted to make the application handle and device context global which is sort of handy but I don't want any part of my program attempting to change it, I do this.

1
2
3
4
5
lockvar<HWND> g_hWnd; // variable declared can still be changed.
lockbar<HDC> g_HDC; // variable declared can still be changed.

g_hWnd.set(what ever returns an application handle 'hWnd'); // now set and cannot be changed.
g_HDC = GetDC(g_hWnd.get()); // get value from g_hWnd! 


The idea is you call the set() function only once, after it executes the first time, it sets locked too true, before settig the variable type, it checks to see if it is locked, if it is, it doesn't do anything which, is the intended design...of course, you could always make it return some type of error, so I guess it still needs a bit of work.

I tried overloading the = operator so that I could do this...

1
2
3
lockvar<HWND> g_hWnd;

g_hWnd = what ever returns a window handle here;


Didn't work the way I wanted it too or maybe I just don't know how to do it. If I can make the = operator assign the value and make the class store it inside its own variable varType, that would be awesome but then how do we get the value out?

 
somefunction(g_hWnd,whatever);


The above just seems impossible, since g_hWnd is some sort of type, how could you make it return the value it has stored if only g_hWnd is specified.....lol what i'm thinking and trying to do right now might not be possible in C++ at all, altho, there are clever people out there!
Last edited on
closed account (3pj6b7Xj)
OMG I made it work!! I never really understood templates or operator overloading, actually I rarely used that stuff, here is the new code!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
template <class T>
class LockAfter
/* This is meant to be used with variables that have global scope
 but must not be modified. The type is created and once a value is
 assigned, it is locked and it cannot be modified again. */
{
    public:
    LockAfter() { bLocked = false; /* Unlocked on start. */ }

    void Set(T varType_)
    {   /* This function stores varType_ in varType. */
        if (!bLocked)
        {   /* Modify varType only when not locked. */
            varType = varType_; // Store the value in varType.
            bLocked = true; // Lock now to prevent further changes.
        }
    }

    T Get() { return varType; /* Returns the value in varType. */}

    LockAfter & operator=(T varType_)
   {   /* This function stores varType_ in varType. */
        if (!bLocked)
        {   /* Modify varType only when not locked. */
            varType = varType_; // Store the value in varType.
            bLocked = true; // Lock now to prevent further changes.
        }
    }

    protected:
    bool bLocked; // Can be locked or unlocked.
    T varType; // This is were the value for the type is stored.
};


Now you can do this!

 
g_hWnd = what ever returns a window handle;


Now if I could just figure the last part, so I can do this...

 
HDC mywindowDC = GetDC(g_hWnd);


Then I put this puppy in a header file and i've got a find handy dandy template, lol.
thats very nice work good job! im just screwing around making a text based rpg right now to practice on what i know. its actually taught me alot on structure of c++ :D and im very happy about that.
closed account (3pj6b7Xj)
I'm glad for you, I think we have both learned something today :) Also I just figured out I can achieve what i'm trying to do because...why is this even possible...?

1
2
3
4
5
6
7
8
9
10
11
12
void printstr(string mystring)
{
     cout << mystring;
}

string mystring;
mystring = "i live in a very big house."
cout << mystring;

string fastcar;
fastcar = "top fuel dragster 0 to 314mph in 3.32seconds!";
printstr(fastcar);


I know for a fact that string is a class in the STL and if they can pull that off, so can I...assuming I figure it out. fastcar is a string but its also an instance of class string, so upon putting fastcar in the printstr function....fastcar must obviously return what ever value its holding within, which...is the string it has stored! so if I could figure that part out...I could implement the same idea into my little template and then I can work out the rest of the kinks.

Now if I could just figure the last part, so I can do this...

HDC mywindowDC = GetDC(g_hWnd);



You make a type conversion member function:
1
2
    //Conversion aoperator to type T
    operator T (){return varType;}


Now you can do this
1
2
3
lockvar<HWND> g_hWnd;
g_hWnd = what ever returns a window handle here;
HDC mywindowDC = GetDC(g_hWnd);


closed account (3pj6b7Xj)
OMG OMG OMG OGM IT WORKS!!! tHANK YOU so much!! I was up all night trying to figure this out and it was so simple! 3 years of programming and I dind't know this stuff!
closed account (3pj6b7Xj)
Here is the resulting code...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
template <class T>
class LockAfter
/* This template creates the variable type in T, once a value is assigned,
 it is locked and cannot be modified again, becoming a constant, in theory.
 (i.e An application handle can be created before the main program but not made
  constant because you cannot set a value until the window is created) */
{
    public:
    LockAfter() { bLocked = false; /* Unlocked on start. */ }

    LockAfter & operator=(T varType_)
    {   /* This function stores varType_ in varType. */
        if (!bLocked)
        {   /* Modify varType only when not locked. */
            varType = varType_; // Store the value in varType.
            bLocked = true; // Lock now to prevent further changes.
        }
    }

    operator T() { return varType; /* Type conversion member function. */ }

    protected:
    bool bLocked; // Can be locked or unlocked.
    T varType; // This is were the value for the type is stored.

    /* Big thanks: levijgraham, guestgulkan. */
};


I hope somebody else finds this useful, you may want to prevent the following; attemping to assign a value of the wrong type..example...LockAfter<HDC> gl_HDC; gl_HDC = CreateWindowEx(blah blah blah); CreateWindowEx returns a window handle which is of the wrong type for LockAfter<HDC> which will probably cause a compiler error, or a runtime error. Noow...if you guys don't mind, I will implement those features in and put this little template in a header file for my own personal use, thanks again all, great little morning project comes to a close. :)

To put it in laymans terms in what LockAfter does...say you have a box but you can't put anything in the box until you get to a destination, once you put something in the box, you lock it and you throw the key away. Now you've still got somethhing in the box but you can't open it and put something else in...lol In other wods, for variables which you want constant...like you can't say: const HWND hWnd; you MUST initialize it first but because you have not created the window, you can't set it as a constant, the only way to make it constant is to initialize from within main const HWND hWnd = CreateWindowEx(); but now it doesn't have global scope ..... LockAfter lets you create the type and then locks when you assign the value to it, this allows you to make the variable a global constant with no stored value but then locks or becomes constant once you do so....generally it is bad practice but hey, who says you can't put it to good use? lol
Last edited on
Topic archived. No new replies allowed.