It is currently Fri May 26, 2017 11:25 pm




 Page 1 of 1 [ 17 posts ] 
Author Message
 Post subject: how to have common variables shared in multiple files??
PostPosted: Fri Jun 27, 2008 2:02 pm 

Joined: Fri Jan 04, 2008 2:11 pm
Posts: 72
well i think this is a bad programming practise but i want some of my .cpp files to share some common variables..how can this be done??

ie display.cpp , init.cpp , quit.cpp all can acess the same structure object declared in main.cpp.


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Jun 28, 2008 5:43 am 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
You could create a global variable, but then everyone would have access to it, not just the classes that you mentioned. You can do this just by declaring your variable like this:

float fMyGlobal;

put this line of code anywhere that all files will see it (ie core.h)

Using globals is not a good idea. It is far better to pass your variable to all your classes by reference so that you can control who can and can't see it.

I did this exact thing with the ErrorHandler and the UserSettings classes, but it could have just as easily been one variable rather than a class.


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Jun 28, 2008 5:48 pm 

Joined: Tue May 01, 2007 2:55 pm
Posts: 96
Location: Behind you
In many cases it might be overkill, but friendships may also provide such functionality.l


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Jun 28, 2008 6:08 pm 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
Friendships break the foundations on how classes work (and protect their data) therefore I would not recommend using them. If you structure your code correctly, you should NEVER have to use friends.


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Jun 28, 2008 8:05 pm 

Joined: Tue May 01, 2007 2:55 pm
Posts: 96
Location: Behind you
That's simply nonsense. They are not in the language not to be used.

Let me give you an example. If one would decide to break up the GameOGL class from your GameEngine into a Game class and an OGL class, then that would not be bad decision, as both are actually different things (the main loop of the game and the part that does the drawing), and it would actually make it easier to change the drawing engine you use, as it means you will really only have to change the OGL class.
However, the two classes would have to quite bit of juggling with mutexes and such to get the game started - where friendship would come in handy to prevent such ugly bits and pieces to make a better start and then let the two go about indepently. And that's just one random example.

There are many, many cases in which friendship is not suited, and few in which it is. However, this makes never quite a bit of an overstatement. One should avoid friendship because he or she understands the negative sides, not because one has been taught never to use it.


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Jun 28, 2008 9:56 pm 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
I'm going to have to disagree with you Jasper.

There are a few things built into C++ that should not be used. goto is another example. Sure you could use it as a branching/looping structure.... bad idea and bad design. There are better and safer ways to do it. Same thing goes with friends. Of the 15+ years that I have been programming in C++ I have NEVER had to use a friend once.


Offline
 Profile  
 
 Post subject:
PostPosted: Sun Jun 29, 2008 8:12 pm 

Joined: Thu Nov 29, 2007 9:44 pm
Posts: 22
I'm going to have to agree with Marek. I am approaching my second decade of programming and I have never had cause to use friends in classes.

Just because something was put in doesn't mean you should use it either.


Offline
 Profile  
 
 Post subject:
PostPosted: Sun Jun 29, 2008 8:13 pm 

Joined: Tue May 01, 2007 2:55 pm
Posts: 96
Location: Behind you
Marek wrote:
I'm going to have to disagree with you Jasper.

There are a few things built into C++ that should not be used. goto is another example. Sure you could use it as a branching/looping structure.... bad idea and bad design. There are better and safer ways to do it.

True, one should prevent the usage of goto, but that is not to say you can NEVER use it. There are cases in which goto is the right solution - however, those are so few, most people will never have them pop up, so telling one never to use it suffices in most cases.
Marek wrote:
Same thing goes with friends.

Yes the same thing goes, usually you want to prevent them, but there few cases in which using them is not all that bad. There are just so many more than with goto and goto has so many more drawbacks that the comparison is far from fair.
Marek wrote:
Of the 15+ years that I have been programming in C++ I have NEVER had to use a friend once.

Now wait, just take a breath and read that again. You have never had to use a friend. Nor have you ever had to use an if statement - you could always instead use the following construction:
bool doneOnce = false;
while (condition && !doneOnce)
{
     content...
     doneOnce = true;
}

(or one could use a for-statement, which would fold the whole bit back into one line again) Does this make using if statements bad? Not at all. Instead it shows that in programming there is a way around everything, thus if you don't want to use something (because you were taught it was "evil" and should NEVER be used, possibly) you will feel that you can do without.

What I would like to hear is your reaction on the example I gave. Do you consider keeping the game loop separate from the drawing engine a mistake? Or do you just say that should be done by juggling with mutexes? Why can't one use friendship in this case? (other than it just being evil)


Offline
 Profile  
 
 Post subject:
PostPosted: Sun Jun 29, 2008 9:21 pm 

Joined: Thu Nov 29, 2007 9:44 pm
Posts: 22
You will never convince me that using a goto is a good idea. You keep saying that we were taught that using these types of statements were evil and that is why we are choosing not to use them. This is simply not true.

I think it is safe to say that people with way more experience than school like Marek choose not to use these because of years of experience and not educational propaganda.


Offline
 Profile  
 
 Post subject:
PostPosted: Sun Jun 29, 2008 9:30 pm 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
Jasper wrote:
What I would like to hear is your reaction on the example I gave. Do you consider keeping the game loop separate from the drawing engine a mistake? Or do you just say that should be done by juggling with mutexes? Why can't one use friendship in this case? (other than it just being evil)


Making the game loop separate from the rendering part is completely fine. When I first started off with the game engine videos I was going to make it work with both OpenGL and DirectX but as I got further into it, I relaxed the code alot and ended up only using OpenGL that is why you'll see the interface is not ideal anymore.

Even if you do split it up, you will not need any friends in your classes.


Offline
 Profile  
 
 Post subject:
PostPosted: Mon Jun 30, 2008 3:46 am 

Joined: Tue May 01, 2007 2:55 pm
Posts: 96
Location: Behind you
morphius wrote:
You will never convince me that using a goto is a good idea. You keep saying that we were taught that using these types of statements were evil and that is why we are choosing not to use them. This is simply not true.

I think it is safe to say that people with way more experience than school like Marek choose not to use these because of years of experience and not educational propaganda.


I ma not trying to convince you to use goto, as that's what I am not saying. All I am saying is that there will be some obscure code samples where it is the right choice, but these are so obscure that barely anybody will ever see them.
The problem with the experience vs school is what the experience actually constitutes. If you have 15 years of experience, but all this time you avoided the use of friends, you actually have no experience with friends - thus, with no experience and some schooling, I guess the avoiding it comes from the schooling, as there is no experience for it to come from.
Of coarse, this becomes a different story when you have tried using "something", but found it to be useless to you and stopped using it all together. However, note that even in this case you might have overseen a very useful case and thus it might actually be useful.

As for GameOGL: okey, just wanted to know that. I am still wondering how you would implement that (yes, I actually tried to do it, without friendship, and had a hard time with the mutexes and timing and everybody having all the data it wanted; in the end I just used a platform independent library that did not need all that, as I would have gone for platform independence in the next step anyway).



I guess the best thing we can do right now is just agreeing to disagree.


Offline
 Profile  
 
 Post subject:
PostPosted: Thu May 20, 2010 11:46 am 

Joined: Tue May 01, 2007 2:55 pm
Posts: 96
Location: Behind you
This is a very old topic, but as I was writing some code and found that friendship was a possible solution, I immediately thought back to this discussion.

So, just out of curiosity (and perhaps to see if there's a better alternative to my code), I ask: How would you do the following thing without friendship?

class MyWrapper
{
public:
    class Iterator;
private:
    list<MyClass> objects;
public:
    Iterator begin();
    Iterator end();
}

class MyWrapper::Iterator
{
private:
    list<MyClass>::iterator it;
public:
    ~Iterator();
    // things like operator++ here
private:
    // private to keep the internal workings (using a list) separate
    // from the interface of the class
    Iterator(const list<MyClass>::iterator& i);
    friend class MyWrapper;
}

MyClass::Iterator MyClass::begin()
{
    return Iterator(objects.begin();
}

MyClass::Iterator MyClass::end()
{
    return Iterator(objects.end());
}

MyClass::Iterator::Iterator(list<MyClass>::iterator i)
{
    it = i;
}


Offline
 Profile  
 
 Post subject:
PostPosted: Fri May 21, 2010 9:22 am 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
Jasper, could you write up a paragraph or two describing what you are trying to do with this code. Explain what MyClass and MyWrapper are for and demonstrate how you plan on using them.

I will then rewrite your code without any frends.


Offline
 Profile  
 
 Post subject:
PostPosted: Fri May 21, 2010 11:22 am 

Joined: Tue May 01, 2007 2:55 pm
Posts: 96
Location: Behind you
I didn't think the actual functionality would have mattered, but here's what they are supposed to do.

I am working on a card game- in which MyWrapper is actually a CardPile. CardPile is a base class from which things like your deck, your hand and your graveyard inherit.
MyClass is actually Card*. The Game object will hold a std::vector<linked_ptr> of all cards, thus being the owner of the cards, as such it is safe to use Card* here.

In order to allow the GUI classes to interact with the cards in certain CardPiles, I decided to implement CardPile::Iterator (example use cases: CardPilePopup will display all the contents of a CardPile in a list, HandDisplayer keeps a Hand::Iterator to remember which card is being displayed in the big pane (that together with a text card list is the current way of displaying the hand)).

So a quick review:
typedef CardPile MyWrapper;
typedef Card* MyClass;


Offline
 Profile  
 
 Post subject:
PostPosted: Wed Jun 09, 2010 2:07 pm 

Joined: Tue May 01, 2007 2:55 pm
Posts: 96
Location: Behind you
So, have you been able to do this without friends, or do I need to provide more information?


Offline
 Profile  
 
 Post subject:
PostPosted: Sun Jun 13, 2010 8:16 pm 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
I would base the classes around how the real objects would be handled in the card game.

I'd probably create an std::vector that would contain an ordered list of all the cards in the game (shuffled at the beginning of the play).

Then each persons hand would be represented by an std::list of card objects. As cards come off the main deck, they get popped off the top and inserted into players' hands. Once discarded, the cards go onto a graveyard std::vector.

Manipulation of the cards can be done through each players "hand" class:

so something like this:
class DeckOfCards {
private:
   std::vector<Card*> m_deck;

public:
   DeckOfCards() {
      for(int i=0; i<52; ++i) {
         //init each card and push it onto m_deck;
      }
      //shuffle deck
   }

   Card* drawCard();
};

class Hand {
private:
   std::list<Card*> m_cards;
   
};
     


Offline
 Profile  
 
 Post subject:
PostPosted: Sun Jun 13, 2010 11:25 pm 

Joined: Tue May 01, 2007 2:55 pm
Posts: 96
Location: Behind you
That's basically how it's working right now. However, my Hand class and Deck(*) class share a base class that implements most of their functionality - CardPile (which is the base class for a couple more similar classes as well)

The biggest difference between our strategies is that I use a list for the deck as well. This had the advantages that it will be painless to make it possible to search a deck for a certain card and eg. put it in your hand and that I was able to make a single base class for my hand and my deck. Shuffling is done by copying the content of the list to a temporary vector, shuffling that vector and copying the elements back to the list. This is still O(n) and it wouldn't have to happen to often anyway.

However, you do not address the necessity of the iterator. The iterator is quite necessary. For one, it is used by the GUI (which is a layer on top of the actual game, which could very easily be swapped out for a different GUI) to keep track of the "current card" in the hand - the one for which the "play" button will work right now. I am sure that I will change the way that works in the future, but just not right now.
But even if I rework that bit of the code, the iterator is quite essential. The larger part of the game is dynamically loaded from external files. So for example a card should be able to state "all cards in your opponent's hand with attack of x or higher are discarded", which makes a lot of sense to do such "all cards in hand/deck/graveyard" kind of thing through an iterator.

The friend statement is how I kept the public interface separated from the implementation (using a std::list) so that if I one day I decide that Decks and Hands need different container types after all, this does not have any effect on the public interface.

(*) I recently renamed my Deck class Library, to keep the term deck for the set of cards you bring to a game (something of constant size) while library refers to the pile you draw from (and that shrinks as you do so)


Offline
 Profile  
 
Display posts from previous:  Sort by  
 Page 1 of 1 [ 17 posts ] 


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  

cron