Advertisement

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

Started by April 12, 2016 06:30 AM
22 comments, last by alh420 8 years, 8 months ago

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.

Logging in from unsecured wireless, I hope no-one steals my password (October 22, 2016)

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.
Advertisement

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...

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.

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

Logging in from unsecured wireless, I hope no-one steals my password (October 22, 2016)

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.
Advertisement

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.

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.

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).

Inspiration from my tea:

"Never wish life were easier. Wish that you were better" -Jim Rohn

soundcloud.com/herwrathmustbedragons

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:

Logging in from unsecured wireless, I hope no-one steals my password (October 22, 2016)

This topic is closed to new replies.

Advertisement