Sign in to follow this  
jeffkiwi

I need a book (or somebody's project source code) which properly explains OOP

Recommended Posts

As mentioned in other threads I've "borrowed" (indefinitely) Bjarne Stroustrup's book, and I own Jazon Yamamoto's book The Black Art Of Multiplatform Games Programming. Neither of these books properly explain OOP (type objects). Bjarne Stroustrup's book, obviously, uses very detailed examples each which build on the previous. Very little of it makes sense to me and most of his chapter on OOP is snippets of code, not complete programs. Jazon Yamamoto's book has very elaborate example code - there's a space shooter game included - but the code is spread over 20 or 30 files. I can find a function prototype but then I struggle to find the function call. It's an expertly written program structured to be extendable, not structured easy to understand - "easy" would be poorly structured, with nearly everything in one or two files.

 

So...

 

I'm after a programming book (ideally C++ but possibly C# or Java) that properly explains how to handle custom objects. I know how to create an instance of something in C++ but then I have no clue how to call a function specific to the object's class. I thought Yamamoto's book would have covered this in easy-to-follow detail but his focus is on SDL, not the specifics of how to create an instance of a class and then call its functions to verify that it was set up.

 

There is heaps of programming books out there and all of them do a good job of explaining variables and functions but it seems none of them (none that I own) explain OOP in a practical way. Perhaps there is a book dedicated to the subject, but then I fear it will focus more on expert gibberish. Opinions please! Just be sure to state your experience, e.g. are you qualified, how many years have you been writing good code for.

 

Of course, if you have a simple game or program which is only one or two fairly small files you could simply email them to me and I'll take them apart :) That's how I learned OOP in Blitz Max, back when I was 16. I found a program that created objects and put them in lists, then it read through the list and drew the objects at their coordinates. I also learned to use type methods and calls to "self". Of course, C++ is a different story as it's much harder.

Share this post


Link to post
Share on other sites

In your post you state that you already know OOP but you don't know OOP with C++. That is pretty much how I started out. I knew a few other languages and had years of programming practice but only used C++ for a few arduino projects before.

 

I started coding in C++ because of one specific project. So I used the code that already was there and the internet as a reference. The main oop related thing that I did not know from the programming languages I used before was the proper use of pointers and references so for the most part that is the important stuff I needed to learn.

 

Make sure your C++ books are up to date (there are some great features in C++11 and C++14) because C++ is evolving and in a good way, too.

Also make sure to not shoot yourself in the foot by using raw pointers. Most of the time you won't need them (you want to use smart pointers in many cases). 

 

There is still a lot not alright with this code but have a look at how an instance of the GameController is created  and how methods are called on the instance https://github.com/GlPortal/glPortal/blob/master/source/Game.cpp

this should at least get you started.

Edited by glportal

Share this post


Link to post
Share on other sites

See these  "Learn something in 24 hours" or "Teach yourself something in 21 days" books. ( for example java or c or c++ ). Very good for beginners in my opinion. But of course you won't learn anything in 21 days, you will just have a solid start. And after you know everything from these books, go to google, write "lazyfoo SDL tutorials" and you are going to start making very very cool 2d games.

Edited by Heelp

Share this post


Link to post
Share on other sites

C++ is not that much harder than any other language. You learn one, you learned them all. Right? ;)

 

I don't even think you need a book at this point. If you know how to program and want tips on OOP, I recommend Derek Banas on YouTube.

 

Highly recommended -->

Design Patterns Playlist

 

Never watched this, but probably useful -->

OOP Playlist

 

thenewboston on Youtube has stuff specifically for C++ in bite-sized videos. No simpler explanations on the web than this guy's.

C++ Playlist

Share this post


Link to post
Share on other sites
Ah that makes more sense now. I wondered why I couldn't do object.classFunction and it's because I didn't do the Class class thing as seen below in the first line:
 
MusicObserver musicObserver;
musicObserver.addCallback(Event::loadScene, std::bind(&MusicObserver::loadMap, musicObserver));

Share this post


Link to post
Share on other sites

Aha!

 

#include <iostream>


using namespace std;


// The abstract class
class Thing{
    public:
        Thing (int, int);
        int x;
        int y;


        giveX(){return x;}


    };


// The proto-type?
Thing::Thing (int a, int b){
x = a;
y = b;
}


int main()
{
    // The constructor?
    Thing thing (10, 12);
    cout << "Hello world!";
    cout << thing.giveX() << endl;
    return 0;
}

It's an ugly output, it really needs a newline character but it does give me "hello world!10" 10 being the value of thing.x - so it works.

Share this post


Link to post
Share on other sites

Your terminology is off.

 

What you call the "abstract class" is actually just a "class" - it's a definition of the data and behaviour for an instance of that class - an "object."

What you call the "prototype" is actually the definition of a constructor - a function that is called when an object is initialized or "constructed."

 

Judging by the content of your posts, I suspect you don't know OOP as well as you think you do, or learned it from a source that doesn't use the same terminology as the rest of the industry. It may help us give further advice if you were to more explicitly state your understanding of what it means to be "object-oriented" and, indeed, what an "object" is. For example, what do you mean when you say "type object?" While I have no direct experience with Bjarne Stroupstrup's book (nor am I even sure which book you're referring to), I imagine it should explain the gist of what you're looking for if perhaps not in terms you're familiar with.

 

Also, since part of the utility of OOP is managing the complexity of larger programs, you'll find that most "practical examples" of it are likely to be much larger than 2 files - "expertly-written programs structured to be extendable" is kind of the point of object-oriented design. In a well-written object-oriented program (or really any program, for that matter), you shouldn't need to understand the entire program to understand what any given piece of it is doing. If you need to understand the whole program to understand a piece of it, then your design is a failure. ;)

Edited by Oberon_Command

Share this post


Link to post
Share on other sites

Yes, I suspect that "abstract class" is a term one uses when there is an abstract class, with inheritance used for sub-classes - hence, the original class (not actually used directly) is called the abstract class. I'll edit my file now and add the proper terms  :)

Share this post


Link to post
Share on other sites

For OOP I would recommend the book "The Object Oriented Thought Process" by Matt Weisfeld. He tries to explain OOP in a language-agnostic way, but of course the code examples he provides throughout the book are in Java, however at the end of the chapters he also includes the code examples in C# and Visual Basic, but throughout the book he also mentions tips/differences in C++.

I have the 3rd edition of this book, the current edition is the 4th edition and I really don't know how much it has changed.

A great source for starting out with C++ would be to read the tutorials on learncpp.com. This site is completely free and has a collection of subjects in C++. Recently the author is updating them.

Then I'd recommend to try to get your hands on these books:

- "Effective C++", 3rd Edition by Scott Meyers, and
- "Professional C++", 3rd Edition by Marc Gregoire.

The book by Scott Meyers offers a handful of tips to avoid common pitfalls in C++, and the the book by Marc Gregoire is similar, except it goes into more detail and is more recent (covers some aspects of C++14 & C++11). However, these books are kind of intermediate C++ level, get them once you feel comfortable with C++'s basics.

And finally, sorry for my English since it is not my native language.

Edited by yazder

Share this post


Link to post
Share on other sites

Yesterday I was asking for an example of a program that creates instances and draws them on the screen. Now I've made it myself, and it even works without crashing:

 

Thing thing (10, 12);
Thing thing2 (25, 25);
thing.DrawMe(wallGFX, screen);
thing2.DrawMe(wallGFX, screen);
Now... apparently I just need to create a vector which stores pointers to each instance of Thing, then I should be able to make a for loop go over each object and draw the bitmap at the location of each instance.
 
In response to yazder: thanks, I might buy some more books when I have money.
Edited by jeffkiwi

Share this post


Link to post
Share on other sites

Nearly there.

 

class Thing{
    public:
        Thing (int, int);
        int x;
        int y;
        SDL_Rect ThingRec;


        void DrawMe(SDL_Surface* pic, SDL_Surface* vid)
        {
            SDL_BlitSurface(pic, 0, vid, &ThingRec);
        }
};




Thing::Thing (int a, int b)
{
    x = a;
    y = b;
    ThingRec.x = x;
    ThingRec.y = y;
    ThingRec.w = (x + 32);
    ThingRec.h = (y + 32);
    list<Thing*> MyList;
    MyList.push_back(this);
}

And the next part where all the errors start:

 

for ( list<obj*> LocalList = MyList; LocalList != list.end(); ++it )
    {
      obj.DrawMe(wallGFX, screen);
    }

It says I need to define obj but I thought using it in the local scope meant it didn't need to exist. I tried editing the above two sections again to keep the list outside the class definition and hopefully it's like a global variable, available everywhere:

 

class Thing{
    public:
        Thing (int, int);
        int x;
        int y;
        SDL_Rect ThingRec;


        void DrawMe(SDL_Surface* pic, SDL_Surface* vid)
        {
            SDL_BlitSurface(pic, 0, vid, &ThingRec);
        }
};


list<Thing*> MyList; // Here's the list


Thing::Thing (int a, int b)
{
    x = a;
    y = b;
    ThingRec.x = x;
    ThingRec.y = y;
    ThingRec.w = (x + 32);
    ThingRec.h = (y + 32);
    MyList.push_back(this);
}

Second section. I'm sure this now makes more sense than the previous one. Obviously it still doesn't make sense to the compiler :unsure: 

 


for ( int it = list.begin(); it != list.end(); ++it )
    {
      MyList(it)->DrawMe(wallGFX, screen);
    }

 

As you can see I have no idea what I'm doing. I'm taking lines of code of random websites and pasting them into my program, then when it doesn't compile I move parts around so that stuff is (I hope) in the scope it's meant to be in. This is the technique I used to learn Blitz Max, and it works, because I can use Blitz today and instantly make a program which uses OOP, even though I haven't used Blitz since 2006  :lol: 

 

Do you know how many weeks I spent copying and pasting before I found a way to make it work? If I remember it took about 1, 2 or perhaps 3 months until I had a working game that used OOP. I played it in maths class against my teacher but I accidentally planted a bomb and then moved into an alcove, trapping myself. Good times. I get confused with C++ because there is example code on how classes work, there's example code on how lists work, and there's example code on how pointers work, and there's explanations about how scopes work but I'm trying to combine all 4 and there's no tutorial on that. If I can get this program to run I'll expand it and make it into a tutorial for people even stupider and more clueless than me.

 

Btw about my other thread, I found that it's easy to set up SDL if I copy the .a and .lib files into C:\Program Files (x86)\CodeBlocks\MinGW so that the MinGW compiler can find them instantly. All I need to do really is go "create new SDL project" in Code Blocks lol too easy.

Share this post


Link to post
Share on other sites

Yes, I suspect that "abstract class" is a term one uses when there is an abstract class, with inheritance used for sub-classes - hence, the original class (not actually used directly) is called the abstract class. I'll edit my file now and add the proper terms  :)


You suspect wrongly. An abstract class is a class which contains one or more pure virtual member functions. An abstract class cannot be instantiated because the compile prevents you from doing that. A lot of base classes are not abstract even when they are seldom or never intended to be instantiated.

Share this post


Link to post
Share on other sites

As you can see I have no idea what I'm doing. I'm taking lines of code of random websites and pasting them into my program, then when it doesn't compile I move parts around so that stuff is (I hope) in the scope it's meant to be in. This is the technique I used to learn Blitz Max, and it works, because I can use Blitz today and instantly make a program which uses OOP, even though I haven't used Blitz since 2006  :lol:


This is not a method I would recommend to learn any language, least of all C++ where a lot of things can "appear to work" very easily while blowing up in your face later (sometimes much later, as in weeks or months).

Your problems are not really related to OOP though but essential bits of the language, like scoping.

This might be actually a disservice to you, but:
[source]
class Thing
{
public:
Thing(int a, int b)
:x(a),y(b)
{
ThingRec.x = x;
ThingRec.y = y;
ThingRec.w = (x + 32);
ThingRec.h = (y + 32);
}

void drawMe(SDL_Surface* pic, SDL_Surface* vid) const
{
SDL_BlitSurface(pic, 0, vid, &ThingRec);
}
private:
int x;
int y;
SDL_Rect ThingRec;
};

int main(int argc, char* argv[])
{
std::list<Thing> myList;
myList.push_back(Thing(10, 12));
myList.push_back(Thing(11, 13));

for (const Thing& thing : myList)
thing.drawMe(/* whatever */);
}
[/source]

On a sidenote, when I see "using namespace std;" in a file I have the urgent need to punch the author.

Edit: Mhm. Apparently the darn forum editor does not even allow me to preserve spaces anymore. Apparently not a week can go by without it becoming ever slightly more broken...

Share this post


Link to post
Share on other sites

Jazon Yamamoto's book has very elaborate example code - there's a space shooter game included - but the code is spread over 20 or 30 files. I can find a function prototype but then I struggle to find the function call. It's an expertly written program structured to be extendable, not structured easy to understand - "easy" would be poorly structured, with nearly everything in one or two files.

 

I think you should give Jazon's code a bit more of your effort.

I havn't looked through it, but I highly doubt it isn't written to be easy to understand, since it is example code from a book.

20-30 files is a quite small C++ project, and you should be able to wrap your head around it if you just try a bit harder.

It is normal to have 2 files per class in C++, so that should just be 10-15 classes. 

Really not that much.

 

(As a real world example, our latest iOS game, which is on the small and simple side (even though the graphics are gorgeous), has approximately 300 source files, and that is just application code, there are another 900+ files in our engine library it uses)

 

If you have problems finding stuff, learn and use the functions in your IDE that are there to help you with exactly this. You have shortcuts to jump to definitions and declarations, and if that is not enough, just open the search and search for it in all files in the project. Then you are guaranteed to get all places where the function/class/variable in mentioned.

Pen and paper can also be useful when mapping out and trying to understand source code.

 

Copying and pasting stuff and permutate it until it "works" is a horrible idea for any programming, and for C++ in particular.

Learn how it works, and you will be writing much less error prone code much faster.

 

Programming is like a puzzle game, or LEGO. Lots of pieces that can fit together in multiple ways, and in many cases there is not one "right" answer you can google up. You just need to understand what you want to do and what pieces are available. Then put them together in the way you choose.

Edited by Olof Hedman

Share this post


Link to post
Share on other sites

 

This is not a method I would recommend to learn any language, least of all C++ where a lot of things can "appear to work" very easily while blowing up in your face later (sometimes much later, as in weeks or months).

Your problems are not really related to OOP though but essential bits of the language, like scoping.

This might be actually a disservice to you, but:

 

 

I see, there's a bit of pseudo-code there and there's a missing capital where my code had one. No matter; I'm sure I'll learn something from your corrections! I've just done some reading on scopes and FOR loops. It seems you're using an index loop, I didn't know such thing existed.

 

 

I think you should give Jazon's code a bit more of your effort.

I havn't looked through it, but I highly doubt it isn't written to be easy to understand, since it is example code from a book.

20-30 files is a quite small C++ project, and you should be able to wrap your head around it if you just try a bit harder.

It is normal to have 2 files per class in C++, so that should just be 10-15 classes. 

Really not that much.

 

(As a real world example, our latest iOS game, which is on the small and simple side (even though the graphics are gorgeous), has approximately 300 source files, and that is just application code, there are another 900+ files in our engine library it uses)

 

If you have problems finding stuff, learn and use the functions in your IDE that are there to help you with exactly this. You have shortcuts to jump to definitions and declarations, and if that is not enough, just open the search and search for it in all files in the project. Then you are guaranteed to get all places where the function/class/variable in mentioned.

Pen and paper can also be useful when mapping out and trying to understand source code.

 

Once I've done more C++ I'm sure that Jazon's book will make sense. Plus I'll need to find what-file-includes-what-other-file in the hierarchy. As you mentioned, classes and header files (both short files, usually) make up most of the extra files. As I do more work I'll figure out a method for this: for example if I want to modify the game I might first edit a class from its file, then edit the game engine file where the renderEverything() function is located. At the moment I'm flicking between two books while trying to comprehend the bigger picture of programming, rather than focussing on little details and working in a logical way. At present I think I can realistically achieve my project's goals and also shift my thinking process to a less nonsensical one.

 

----

 

I hope to make an extendible game engine by the end of the year, complete with my own ridiculous graphics. These are 32x32 btw. When you view them in original size you can hardly see anything. You have to use your imagination I guess. That brick wall does look as if it was carelessly stacked. It could come down any minute! Our hero, on the left, will have different camouflage, of course. 

 

pixel_art_demo.png

Share this post


Link to post
Share on other sites

I see, there's a bit of pseudo-code there and there's a missing capital where my code had one.


Except for the elision of the parameters in the call to 'drawMe', it wasn't really pseudo-code. The modification from DrawMe to drawMe was completely intentional since the common camel case convention is to use CamelCase for class names and camelCase for (member) functions and data.

I also changed some types because for example an std::list<Thing*> makes no sense in this context.
 

No matter; I'm sure I'll learn something from your corrections! I've just done some reading on scopes and FOR loops. It seems you're using an index loop, I didn't know such thing existed.

The for-loop I'm using is a ranged for-loop. In the olden days you could have written
[source]
for (std::list<Thing>::iterator it = myList.begin(), end = myList.end(); it != end; ++it)
{
const Thing& thing = *it;
// whatever
}
[/source]
That is a lot of annoying boilerplate though and if you have a compiler which cannot do C++11 at this day and age, you are doing something badly wrong. Edited by BitMaster

Share this post


Link to post
Share on other sites

Looks like you are more looking for specific code than actually learning about OOP. As been mentioned before, OOP is somewhat independent of language ( its stands to reason that the language chosen should be able to express OOP concept and do so efficiently ). There are tons of book that others have mentioned that will be able to guide you along the way. If you do not understand the higher level concepts behind the OOP paradigm ( if I can call it that ), then pouring over someone's code is not going to do you any good. In fact it may lead to more frustration as you will probably spend more time questioning the reason behind specific decisions wrt to the code, questions that probably would have been answered if you understood at an higher level.

Share this post


Link to post
Share on other sites
Looking at the source code for a game always seems to a beginner like it should be a great way to learn, but experience tells a different story.

Understanding is far harder to gain from a dense bunch of code than from reading a well written article or chapter on the subject.

Decide on a realistic target then just start programming. As you encounter each specific problem, break it down into the smallest sub-problems you can then research how to solve each specific sub-problem, one by one. Compare multiple solutions and decide which suits you best. There is rarely one correct answer.

OOP is a tool to solve problems. You need to be fully aware of the problems before there is any chance the solution will help you or make sense.

For that, you need to make lots of mistakes, follow lots of wrong paths and abandon lots of bad code. But when you understand the problems you have created for yourself with bad design, next time you can do better.

Good luck.

Share this post


Link to post
Share on other sites

At the moment I'm flicking between two books while trying to comprehend the bigger picture of programming, rather than focusing on little details and working in a logical way. At present I think I can realistically achieve my project's goals and also shift my thinking process to a less nonsensical one.

 

I think you'd benefit from working on the smaller-scale detail-oriented parts of programming before jumping to exploring how code fits together to do more complex things. You'd be surprised how much faster you'll learn the bigger-picture if you've got a lot of the little-picture under your belt.

 

Also, don't expect your engine to be done (or even started, really) by the end of the year. Expect to throw away a lot of the code that you're writing now and that you'll be writing for some time. We've all thrown away a ton of code, that's how we learn (also fixing code worth fixing so that we don't have to throw it away).

Share this post


Link to post
Share on other sites

I took a few days break from programming and I'm back to the error hunting again.

 

    std::list<Thing> myList;
    myList.push_back(Thing(10, 12));
    myList.push_back(Thing(11, 13));
for (Thing& thing : myList)
      myList()->drawMe(wallGFX, screen);
error: no match for call to '(std::list<Thing>) ()'

So I think the second part there is supposed to get the pointer to the object then access its method. By the error it seems it cannot find the objects, or perhaps it cannot find the list. Both the list and its objects are declared in the main function  :blink:

Share this post


Link to post
Share on other sites

I took a few days break from programming and I'm back to the error hunting again.

 

    std::list<Thing> myList;
    myList.push_back(Thing(10, 12));
    myList.push_back(Thing(11, 13));
for (Thing& thing : myList)
      myList()->drawMe(wallGFX, screen);
error: no match for call to '(std::list<Thing>) ()'

So I think the second part there is supposed to get the pointer to the object then access its method. By the error it seems it cannot find the objects, or perhaps it cannot find the list. Both the list and its objects are declared in the main function  :blink:

 

Take a step back and think for a bit.

 

What does this do? 

for (Thing& thing : myList)

 

With that in mind, which one variable do you always expect to see used in the loop body, regardless of what the loop does?

 

Now you should be able to see the problem.

Edited by Olof Hedman

Share this post


Link to post
Share on other sites

I definitely need to take a step back... I was implementing BitMaster's code into my program and somehow that part was not updated. It was meant to be:

thing.drawMe(/* function arguments here */);

That makes a million times more sense. Instead of trying to call a list as if it were a function, I'm meant to access the object's member function duh. After too many hours in front of the screen (no matter how dimmed) my eyes go blurry and I cease to make sense to myself.

Share this post


Link to post
Share on other sites

After too many hours in front of the screen (no matter how dimmed) my eyes go blurry and I cease to make sense to myself.

 

No worries, happens to us all :)

Sometimes all you need is to go to bed, and the problem is much clearer in the morning.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this