GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 22-Feb-2007, 16:04
Timothy_Bennett Timothy_Bennett is offline
New Member
 
Join Date: Feb 2007
Posts: 11
Timothy_Bennett is on a distinguished road

Beginner working with classes


Hello,

I want to be able to access variables from a class - from another class' member function. It's a little hard for me to simply ask, so I'll give an example:

I have a variable in class X. It is private and uses an accessor function that returns that variable's value. Class Y, however, depends on the value and needs it in an if statement.

Finally, a code example:

Code:
class X { public: //Other member functions bool getVar() const { return theVar; } //More stuff private: bool theVar; }; class Y { //Stuff void myFunc(); //Obviously, I wouldn't ever use these classes and function names. }; ... void Y::myFunc() { if(Ben.getVar) { //Stuff } } ... int main() { X Ben; Y George; George.myFunc(); ... }

Result: Syntax error, Ben is undeclared <- something like that

Um... forgive a stupid question, but... what am I doing wrong, here?
  #2  
Old 22-Feb-2007, 16:22
Euphemism Euphemism is offline
New Member
 
Join Date: Feb 2007
Posts: 12
Euphemism is on a distinguished road

Re: Beginner working with classes


The problem is that your Y class has no idea what Ben is referring to. Later on in the main function, you create an X object called Ben, but (1) Y cannot and should not depend on you creating an object called Ben later on, and (2) Ben is still outside Y's scope.

The easiest way to solve your problem is to use
CPP / C++ / C Code:
void Y::myFunc(X pal)
{
   if(pal.getVar)
   {
      //Stuff
   }
}
And in your main, use George.myFunc(Ben)
  #3  
Old 22-Feb-2007, 16:24
davis
 
Posts: n/a

Re: Beginner working with classes


Quote:
Originally Posted by Timothy_Bennett
Hello,

I want to be able to access variables from a class - from another class' member function. It's a little hard for me to simply ask, so I'll give an example:

I have a variable in class X. It is private and uses an accessor function that returns that variable's value. Class Y, however, depends on the value and needs it in an if statement.

Finally, a code example:

Code:
class X { public: //Other member functions bool getVar() const { return theVar; } //More stuff private: bool theVar; }; class Y { //Stuff void myFunc(); //Obviously, I wouldn't ever use these classes and function names. }; ... void Y::myFunc() { if(Ben.getVar) { //Stuff } } ... int main() { X Ben; Y George; George.myFunc(); ... }

Result: Syntax error, Ben is undeclared <- something like that

Um... forgive a stupid question, but... what am I doing wrong, here?

Y's myFunc is private by default. Declare it public or make X a friend of Y's.


:davis:
  #4  
Old 22-Feb-2007, 21:00
Timothy_Bennett Timothy_Bennett is offline
New Member
 
Join Date: Feb 2007
Posts: 11
Timothy_Bennett is on a distinguished road

Re: Beginner working with classes


Quote:
Originally Posted by Euphemism
The problem is that your Y class has no idea what Ben is referring to. Later on in the main function, you create an X object called Ben, but (1) Y cannot and should not depend on you creating an object called Ben later on, and (2) Ben is still outside Y's scope.

The easiest way to solve your problem is to use
CPP / C++ / C Code:
void Y::myFunc(X pal)
{
   if(pal.getVar)
   {
      //Stuff
   }
}
And in your main, use George.myFunc(Ben)

Argh! I am such an idiot.

I actually was doing this before. Then I stopped for a week to work on school projects (learning C++ on my own time; I'm in high school), came back and forgot why the heck I was doing what I did. I couldn't find a reference anywhere, so I removed the parameters. I am such a fool. Now I have to redo hours of work.

Note to self: Never try to debug when you're angry. (I Shift-Deleted the hpp and cpp. Way to go, Tim. )
  #5  
Old 23-Feb-2007, 19:31
Timothy_Bennett Timothy_Bennett is offline
New Member
 
Join Date: Feb 2007
Posts: 11
Timothy_Bennett is on a distinguished road

Re: Beginner working with classes


Hey, I've decided to start over and I could use a little assistance again.

I decided to write the first two classes (the first one is a major func, but a utility func, so it does nothing by itself) over, and test these out by themselves. Without a fully fleshed program, and only 2 of the 12 ending classes written, the program is at the moment very small. Yet, when I tried to compile the tests for this module of the game, I got 30 errors. I've managed to reduce the errors by a factor of 10, but the last three are very elusive. Basically, it works like this:

I'm writing a command-line-driven game, in efforts to practice OOP and other concepts I am having trouble with. The utility class, game, has a function which passes the second class, tBedroom, as a parameter. This is giving me syntax errors. However, a similar func in class tBedroom can do the same with class game with no errors.

Code:
In the header: typedef unsigned short int USHORT; class game { public: game(); void inventory(tBedroom tBed); //Will need all rooms as parameters eventually. //More stuff }; class tBedroom { public: //Stuff void openDoor(game engine); //Accessors bool getDoorLocked(game engine) const { return doorLocked; } //Other };

The above code, when mixed with my other code, will not compile. It says the following in VC++ Express:

1. error C2061: syntax error : identifier 'tBedroom'
2. overloaded member function not found in 'game'
3.error C2660: 'game::inventory' : function does not take 1 arguments

The lines highlighted by these errors are:

1. void inventory(tBedroom tBed); //In the header
2. void game::inventory(tBedroom tBed) //In the .cpp. Actually, it highlighted the { underneath as a problem, but that's not descriptive
3. engine.inventory(tBed); //In the code that checks functions for logic errors.

I am told to take a look at this line:

{

That line is under the declaration "class game", and above the constructor, game();


Now, it hasn't escaped my notice that the functions in "tBedroom", which pass game engine as a parameter, do not have these errors. Coincidentally, the class "game" is declared first. I think the compiler can't recognize the identifier in "game" because "tBedroom" hasn't been declared yet on that line. But if I were to switch the order, that would, if I am correct, give me twice the grief -- the same errors, but with the other two currently working functions. What can I do to get this to work?
  #6  
Old 23-Feb-2007, 20:15
TurboPT's Avatar
TurboPT TurboPT is offline
Regular Member
 
Join Date: Feb 2006
Location: Atlanta, GA
Posts: 958
TurboPT is a jewel in the roughTurboPT is a jewel in the roughTurboPT is a jewel in the rough

Re: Beginner working with classes


Nope that error is correct...

Let's think like the compiler... ( Dave pointed this out in a another post awhile back, but it is nice to repeat)

So, I'm compiling, starting from the top of the header file, and while going I come across some keywords/types,
(typedef, unsigned, short, int ) with an identifier, and although the int is redundant, so far so good...

Then we get to a class with an identifier 'game'... still good...
followed by a public label...still good,
a game constructor declared... still good,
and then to a void function... and it has arguments, BUT WAIT!!

What the heck is a 'tBedroom' ?? I don't know what this is! It's not a keyword, label, or builtin type -- I have no definition for this?? What the --? ERR.

EDIT: actually I see the problem you originally stated. I believe that each class should reside in it's OWN header file, and you can #include the other to get the definition needed. Or, maybe before the game class, add this (sort of like a prototype):
CPP / C++ / C Code:
 class tBedroom;
__________________
Use the force...read the source!!
WYCIWYG -- what you code is what you get!
  #7  
Old 23-Feb-2007, 22:24
Timothy_Bennett Timothy_Bennett is offline
New Member
 
Join Date: Feb 2007
Posts: 11
Timothy_Bennett is on a distinguished road

Re: Beginner working with classes


The prototype idea worked perfectly. Thanks.
  #8  
Old 24-Feb-2007, 07:13
davis
 
Posts: n/a

Re: Beginner working with classes


Quote:
Originally Posted by Timothy_Bennett
The prototype idea worked perfectly. Thanks.

One of the most important things that we can do as assistants is provide you with the proper terminology. The "prototype idea" is actually a forward declaration.

Though it may sound trite, the preprocessor is not the compiler.

You will want to avoid passing complex objects by value. When you pass by value, you implicitly invoke the copy constructor of the object. Preferred is to pass by reference.

Something is wrong with a design that has us passing an instance of the game engine into operations like openDoor and getDoorLocked. If we assume that you are going to have several classes in your system and that many of them will interact with "game" in some manner, then we'd probably expect to see these classes with a private member attribute of type "game." However, I do not adovocate that design change at this time. More important is to determine how interactions should work based on the nature of them as it relates to their real-world counterparts.

I'd also recommend adopting some form of convention for naming your classes. Some use a capital C in front of every class, some use a capital letter for class names and lower case first letter for operation names and variables (often combined with camel-backing the remaining letters). I would suggest the dominant style for your platform and/or development system as a place to start.

As it is now, we see "game" and "tBedroom" as class names. I'd recommend standardizing on some common naming convention. Usually, when we see a "t" prefixing a name, it means "type" as in a user-defined type. If that is what you meant, then it seems odd that we don't see tGame. If there is some other purpose for the "t," let me know.

One of the things that you're doing is creating interfaces for tBedroom that work on "elements" of a tBedroom, such as the accessor for "door." Imagine that for every possible "room" in a game, that you will need to have "door operations" for every possible door. Now consider how you will go about naming these operations and using them. For example, lets say that you decide to invent a new room in your game that has more than one door. What does getDoorLocked do now? We can see that the operational argument of type game isn't going to offer much help in terms of determining which door we mean. Additionally, if we do figure out some way to implement it, such as uniquely identifying each door operation (e.g.: getSouthDoorLocked, getNorthDoorLocked) we will have to have these operations in every body of code that has doors. Better is probably to have a Door class that encapsulates the attributes necessary to represent a Door and exposes pertinent Door behavior through its public interfaces.

In other words, in object-oriented programming, when we need an object to do something, we don't embed that functionality into an object that is NOT the object that we're trying to use. What this means is that you will get very good at writing classes, as you will eventually discover that you need a class for just about everything that you can imagine. In a class like Bedroom, we'd expect to see a composition of other objects such as Door, Bed, Closet, NightStand, etc. Then, as interactions with these objects are required, they each encapsulate their special functionality. For example, we may locate an instance of Lamp on NightStand. And, since NightStand and Bed are kinds of Furniture, we might have a more generic set of base classes that help us to define the commonality amoung objects of more specific types. For example, the base Furniture class may specify boundaries or other dimensional data points that can be used by the game engine in determining whether or not our player is intercepting the object and therefore needs to interact with it. Since all pieces of Furniture would have some boundaries, it makes better sense to place this kind of functionality in the base and derive specializations such as Bed from it.

This can be rather involved and it can be quite complex when one considers that Furniture::Table::NightStand might very well be a type's hierarchical representation...and we still do not have a "bedroom" yet, just one item in it.

Once we populate a room with objects, we often need a manner of signaling them or otherwise propagating events to them. Observer is a choice. Of course, before we can fruitfully implement the Observer design pattern, we will probably want to come up with some event types so that we can test our implementation.

One of the ways that is said to best learn something is by doing it. They also say that practice makes perfect. The truth is that you can practice the wrong things forever and never become perfect (nor even marginally close). There is also a need to be able to take manageable sized steps while learning. I think that there is an inherent need for one to separate the mechanics of the language from the fundamentals of OO design. Once the fundamentals of the language constructs are understood, then it is reasonable to assume a mission of learning OO design. Therefore, we have the notion of "trivial" projects that teach the mechanics. In other words, I don't think that you've taken enough baby steps yet to begin on the OO side of it. However, a part of me says that it is never too early to start learning as much of it as possible. The challenge is in getting your ever-increasingly more complex code to compile and link when you're still not solid on the basics.

Something that may be an exercise that helps you with your game and teaches you more about the mechanics is to try to think of all of the nouns in your game. Make a list. Door is one. Bed might be another. Try to be singular in every case. For example, Bedroom, while a noun, is really a composition of other nouns. In fact, few things in the real world are "discrete components," even Door has a Knob, some number of Hinge objects, texture, dimensions, clearances and more. As you can imagine, the more true you can be to the design of your objects, the more realistic your game may be. However, it is probably suitable for your purposes to simply design a Door class that is representative of how you want your player to interact with doors in your game. While making your list, consider the real-world counterpart of what you're designing and try to decide what compromises you're willing to make for the sake of brevity and in facilitating your goals for the game and for learning OO. Once you have a list of nouns, begin writing class implementations for them. Explore their needs for operators, constructors, destructors and operations and attributes. As you find that you need some body of code to support some feature of the object, decide how you will test that functionality. Evaluate your test results to ensure that your objects are performing as intended.

If it sounds like a lot of work, it is. It is much simpler to cut corners, too. Software quality is a problem when corners get cut. Just about anyone can code a little. It takes a commitment to code a lot.

And, take a look at how you implement your operations. Do you intend to throw an exception in situations where openDoor fails to deliver on its promise? In spite of having a means for checking to see if the door is locked, if we fail to first unlock a locked door before using openDoor, the only choice in contract programming is to produce an opened door (our promise) or throw an exception (the result if we are unable to fulfill our promise). Do you have a "DoorNotOpenable" exception type planned?


:davis:
  #9  
Old 24-Feb-2007, 16:37
TurboPT's Avatar
TurboPT TurboPT is offline
Regular Member
 
Join Date: Feb 2006
Location: Atlanta, GA
Posts: 958
TurboPT is a jewel in the roughTurboPT is a jewel in the roughTurboPT is a jewel in the rough

Re: Beginner working with classes


Quote:
Originally Posted by davis
One of the most important things that we can do as assistants is provide you with the proper terminology. The "prototype idea" is actually a forward declaration.

Thanks for the clarification Davis, plus all the other good points!
I couldn't get 'declaration' in my thought -- the proto was the closest thing I could derive at the time.
__________________
Use the force...read the source!!
WYCIWYG -- what you code is what you get!
  #10  
Old 27-Feb-2007, 17:13
Timothy_Bennett Timothy_Bennett is offline
New Member
 
Join Date: Feb 2007
Posts: 11
Timothy_Bennett is on a distinguished road

Re: Beginner working with classes


Quote:
Originally Posted by davis
One of the most important things that we can do as assistants is provide you with the proper terminology. The "prototype idea" is actually a forward declaration.

Oh, OK.

Quote:
You will want to avoid passing complex objects by value. When you pass by value, you implicitly invoke the copy constructor of the object. Preferred is to pass by reference.

As I recently discovered. I was testing a code block and it took an hour to figure out why a variable would seem to change, and then revert back to the original.

Quote:
Something is wrong with a design that has us passing an instance of the game engine into operations like openDoor and getDoorLocked. If we assume that you are going to have several classes in your system and that many of them will interact with "game" in some manner, then we'd probably expect to see these classes with a private member attribute of type "game." However, I do not advocate that design change at this time. More important is to determine how interactions should work based on the nature of them as it relates to their real-world counterparts.

I may just be having a horrific moment of idiocy, but I'm not quite positive on what the bolded portion means. Are you talking about inheritance? If so, I could do that fairly easily. As it happens, I'm rewriting a large portion of the code because it was totally barking up the wrong tree. ("It made sense at the time...") So, making any major changes would actually be fairly easy. Please, let me know what I can do to improve.

Quote:
I'd also recommend adopting some form of convention for naming your classes. Some use a capital C in front of every class, some use a capital letter for class names and lower case first letter for operation names and variables (often combined with camel-backing the remaining letters). I would suggest the dominant style for your platform and/or development system as a place to start.

At the moment, I'm using what some would call "Intercaps", which is that the first word is lowercase and subsequent words are capitalized, i.e. "yourClassNameHere".

Quote:
As it is now, we see "game" and "tBedroom" as class names. I'd recommend standardizing on some common naming convention. Usually, when we see a "t" prefixing a name, it means "type" as in a user-defined type. If that is what you meant, then it seems odd that we don't see tGame. If there is some other purpose for the "t," let me know.

"t", in this case, is an initial. This game takes place in my house, and I have siblings. During the first writing, I thought it was a bit error-prone to type out "timsBedroom". However, now that I think about it, it wouldn't be so bad.

Quote:
One of the things that you're doing is creating interfaces for tBedroom that work on "elements" of a tBedroom, such as the accessor for "door." Imagine that for every possible "room" in a game, that you will need to have "door operations" for every possible door. Now consider how you will go about naming these operations and using them. For example, lets say that you decide to invent a new room in your game that has more than one door. What does getDoorLocked do now? We can see that the operational argument of type game isn't going to offer much help in terms of determining which door we mean. Additionally, if we do figure out some way to implement it, such as uniquely identifying each door operation (e.g.: getSouthDoorLocked, getNorthDoorLocked) we will have to have these operations in every body of code that has doors. Better is probably to have a Door class that encapsulates the attributes necessary to represent a Door and exposes pertinent Door behavior through its public interfaces.

An excellent idea. I'm trying to think of a way to do this; let me know what you think of this:

"door" is a class by itself. In the constructor of each room, a door object is created, like this:

Code:
timsBedroom::timsBedroom() { //Other statements door northDoor(); //Other statements }

The "door" class would have variables, such as whether they are locked, whether they are open, etc..

Actually, I could do that for every item in the game, couldn't I?

Quote:
In other words, in object-oriented programming, when we need an object to do something, we don't embed that functionality into an object that is NOT the object that we're trying to use. What this means is that you will get very good at writing classes, as you will eventually discover that you need a class for just about everything that you can imagine. In a class like Bedroom, we'd expect to see a composition of other objects such as Door, Bed, Closet, NightStand, etc.

Oh. I just got my question answered. (That's a big "yes"...)

Quote:
Then, as interactions with these objects are required, they each encapsulate their special functionality. For example, we may locate an instance of Lamp on NightStand. And, since NightStand and Bed are kinds of Furniture, we might have a more generic set of base classes that help us to define the commonality amoung objects of more specific types. For example, the base Furniture class may specify boundaries or other dimensional data points that can be used by the game engine in determining whether or not our player is intercepting the object and therefore needs to interact with it. Since all pieces of Furniture would have some boundaries, it makes better sense to place this kind of functionality in the base and derive specializations such as Bed from it.

Ah... I see. I think I'll rewrite. This makes the whole game sound easier.

Quote:
This can be rather involved and it can be quite complex when one considers that Furniture::Table::NightStand might very well be a type's hierarchical representation...and we still do not have a "bedroom" yet, just one item in it.

True, but I'm beginning to see the benefits in it. Everything has a place, and you can tell more easily where everything is. Wow, I was blind before.

Quote:
Once we populate a room with objects, we often need a manner of signaling them or otherwise propagating events to them. Observer is a choice. Of course, before we can fruitfully implement the Observer design pattern, we will probably want to come up with some event types so that we can test our implementation.

Observer? Not sure what that is.

Quote:
One of the ways that is said to best learn something is by doing it. They also say that practice makes perfect. The truth is that you can practice the wrong things forever and never become perfect (nor even marginally close). There is also a need to be able to take manageable sized steps while learning. I think that there is an inherent need for one to separate the mechanics of the language from the fundamentals of OO design. Once the fundamentals of the language constructs are understood, then it is reasonable to assume a mission of learning OO design. Therefore, we have the notion of "trivial" projects that teach the mechanics. In other words, I don't think that you've taken enough baby steps yet to begin on the OO side of it. However, a part of me says that it is never too early to start learning as much of it as possible. The challenge is in getting your ever-increasingly more complex code to compile and link when you're still not solid on the basics.

I am fully capable of writing classes, functions, et cetera. My problem is that no book I've read teaches proper strategies for writing when you've got multiple classes that need to interact with each other. And I see your point; I probably should practice on that. Then again, I can't think of a better way to learn than to do it and see how I can improve.

Quote:
Something that may be an exercise that helps you with your game and teaches you more about the mechanics is to try to think of all of the nouns in your game. Make a list. Door is one. Bed might be another. Try to be singular in every case. For example, Bedroom, while a noun, is really a composition of other nouns. In fact, few things in the real world are "discrete components," even Door has a Knob, some number of Hinge objects, texture, dimensions, clearances and more. As you can imagine, the more true you can be to the design of your objects, the more realistic your game may be. However, it is probably suitable for your purposes to simply design a Door class that is representative of how you want your player to interact with doors in your game. While making your list, consider the real-world counterpart of what you're designing and try to decide what compromises you're willing to make for the sake of brevity and in facilitating your goals for the game and for learning OO. Once you have a list of nouns, begin writing class implementations for them. Explore their needs for operators, constructors, destructors and operations and attributes. As you find that you need some body of code to support some feature of the object, decide how you will test that functionality. Evaluate your test results to ensure that your objects are performing as intended.

Before I rewrite in the fashions I'm reading here about, I'll be sure to plan it out. I must confess, initially I was basically winging it; I knew what I wanted in a way, but I was shaky on how to get there. Now, I won't be.

Quote:
If it sounds like a lot of work, it is. It is much simpler to cut corners, too. Software quality is a problem when corners get cut. Just about anyone can code a little. It takes a commitment to code a lot.

It doesn't seem so much that it's more work than it is better organized work. Instead of putting doorLocked and doorOpen (both bools) in timsBedroom, I can put them in a door class, then have a timsBedroom.door.doorLocked, etc.. I agree that programming takes a dedication; this can't be learned in a day, as I am the billionth to prove.

Quote:
And, take a look at how you implement your operations. Do you intend to throw an exception in situations where openDoor fails to deliver on its promise? In spite of having a means for checking to see if the door is locked, if we fail to first unlock a locked door before using openDoor, the only choice in contract programming is to produce an opened door (our promise) or throw an exception (the result if we are unable to fulfill our promise). Do you have a "DoorNotOpenable" exception type planned?

Initially, no. I merely wrote code to deal with it with a series of if-then statements. Exceptions would probably be clearer. I intend to use them.

Thank you very much. I'm making a list of the suggestions offered here and printing them. Using this will help me more than anything I've read or done to date.

The only downside of all this is that I'm going to be par-tic-ularly bored when I first start a formal programming class.
 
 

Recent GIDBlogMeeting the local Iraqis by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
htaccess basic authentication just stops working zoolander Apache Web Server Forum 0 12-Jan-2007 12:41
Pointer Usage in C++: Beginner to Advanced varunhome C++ Forum 0 19-Aug-2005 09:25
Assistance with classes... Bravebird C++ Forum 7 27-Apr-2005 13:17
Using map<> with classes crystalattice C++ Forum 3 14-Nov-2004 16:23

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 06:00.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.