Pretty advanced pointer problem

Started by
27 comments, last by krippy2k8 11 years, 8 months ago

I'm sorry Servant of the Lord, I have to disagree strongly.

A "break;" statement in a for loop doesn't make sense. By doing this:

for(vector<Container*>::iterator it = containers.begin(); it != containers.end(); it++)
{
if(!(*it)->getFull())
{
(*it)->addItem(itemAdd);
break;
}
}

You modified a for loop to a while loop. Hence what you really need here is a while loop.

If you want to talk about semantics (and I totally agree about that), then it's not even a while loop you want. The semantics of the code is, in my opinion, "find the first non-full item and add to it if there is one"; thus, std::find_if() and an if-statement.

The semantics of a search in this case is std::find_if, not a while loop.
Advertisement

[quote name='Ripiz' timestamp='1344847640' post='4968984']
I've downloaded Eclipse, went through 3 tutorials and it still couldn't compile Hello World. Piece of crap, not a tool.
Similar thing happened with Code::Blocks, but I removed it right away after it couldn't compile, I didn't bother.

Does it reach line content = itemAdd; in Container::addItem(Item* itemAdd)?


Yes, it's only after that that it crashes. Either when it tries to update "content" variable or when it tries to draw from it
[/quote]

What debugger shows about itemAdd at that line? Is it still Currency type, or not anymore?
If it is, add pointer to watch list, then try to debug further to see when it changes.

[quote name='dimitri.adamou' timestamp='1344803877' post='4968820']
I'm pretty sure with any modern day compiler, your able to stop the execution of code at your desired lines. So start from the top of the stack,

I have a feeling your are slicing, you could try declare your setX and setY as virtual (in the inheritted classes) - or it could be possible that you've casted an object that doesn't even have the setX/setY

As you are calling a Pointer to Item, if you wish to have Polymorphic functionality you need to declare virtual on the desired functions eg

in weapon.cpp

void Weapon::setX(int x)
{
box.x = x;
}


is now


virtual void Weapon::setX(int x)
{
box.x = x;
}


I'm not sure what object Item* is supposed to represent, I've gone through your code briefly but I have not compiled it


I actually doesn't really know how to debug roperly. I've learned myself to use Watches and Call-stack aswell as breakpoints. And as i said in my first post "This code is where it crashes: "content->setX(contBox.x);". If i comment that out it will instead crash on the render function. The reason is that the pointer is no longer (Currency*) but (class Item*) in the "watches window".".

Whilst googeling around on the problem i was having i say some post about slicing. I don't really know what it is thought. Might have to read into that.

Why would i make them virtual in the inheritted classes? What would that change, i only thought you made them virtual in interfaces.

Item* is an interface all the items will be using in the game. At the moment there are only "Weapon", "Armor" and the broken "Currency". this is my first project ever so i'm pretty sure i'll have to rewrite my code from the start at some point, even now i see how much worse i was at coding when i look at the little older code in my project.
[/quote]

Oops. My bad, I went through your code and saw that in item.h virtual is defined.. but it is derived from yet another class.

Your classes are trying to do too much, the design is a bit confusing - you should try seperate everything as much as possible. Someone wrote a really good article on gdev.net, but I can't seem to find it.. it spoke about foward declaration and just maintaining neatness in code


As for slicing here is a simple quick example


class firstclass
{
public:
void hello() { cout << "firstclass::hello();" << endl; }
}

class secondclass : public firstclass
{
public:
int valA;
void hello() { cout << "secondclass::hello();" << endl; }
}


firstclass A;
secondclass B;

A = B; //slicing occurs. valA has no access
A.hello(); // firstclass::hello(); gets printed out


Thats slicing at its bare-basics, but with pointers and virtual tables this can get resolved (after looking a bit deeper in your code that doesn't appear to be the problem)

I haven't spent much time in there though. But yeah, back to my original point - your classes are trying to do too much

[color=#00ff00]Text
Also, don't scrap your code. Even if you decide to rewrite it, it is very useful to have the old code and you can still use large portions of it.


Thank you! That helped alot. I'll have to look further into it thought.

Also i wont ever completely scrap the code in case i actually need something from it.

[quote name='Tallkotten' timestamp='1344849022' post='4968988']
[quote name='Ripiz' timestamp='1344847640' post='4968984']
I've downloaded Eclipse, went through 3 tutorials and it still couldn't compile Hello World. Piece of crap, not a tool.
Similar thing happened with Code::Blocks, but I removed it right away after it couldn't compile, I didn't bother.

Does it reach line content = itemAdd; in Container::addItem(Item* itemAdd)?


Yes, it's only after that that it crashes. Either when it tries to update "content" variable or when it tries to draw from it
[/quote]

What debugger shows about itemAdd at that line? Is it still Currency type, or not anymore?
If it is, add pointer to watch list, then try to debug further to see when it changes.
[/quote]

It is of Currency type in the addItem func.

I've already done that but, i'll have to do it again i guess. Need to get this working

Oops. My bad, I went through your code and saw that in item.h virtual is defined.. but it is derived from yet another class.

Your classes are trying to do too much, the design is a bit confusing - you should try seperate everything as much as possible. Someone wrote a really good article on gdev.net, but I can't seem to find it.. it spoke about foward declaration and just maintaining neatness in code

I haven't spent much time in there though. But yeah, back to my original point - your classes are trying to do too much


Yeah, i've gathered that.

Sp basically i'll have to look up how i use inheritage as well as splitting up my code further into "master classes" that can be accessed to all classes that needs to use that code. So for example instead of having a movement function in both player and enemy i should just make that one function in the Entity class (which is their interface class)? That's what you mean right?

Someone mentioned that my loadFiles class is inherit weirdly. He said that the code is probably being run several times (meaning the files that are loaded are loaded several times). He continued to say that i should look up composition vs inheritance. I'm guessing that after reading up on that i might help to solve some of the problems i am having.
It almost sounds like you have a race condition going on, is there any multi threading involved?

It almost sounds like you have a race condition going on, is there any multi threading involved?


I haven't created any additional threads. So unless they can be created without me actively writing the code for it it's not

I'm sorry Servant of the Lord, I have to disagree strongly.

A "break;" statement in a for loop doesn't make sense. By doing this:

for(vector<Container*>::iterator it = containers.begin(); it != containers.end(); it++)
{
if(!(*it)->getFull())
{
(*it)->addItem(itemAdd);
break;
}
}

You modified a for loop to a while loop. Hence what you really need here is a while loop.
Both works fine, it makes a difference when a Theoretical IT guy needs to verifiy the program.
A for loop is simple, it knows at runtime the exact amount of times the body is executed. A while loop is a bit more complicated. And by camouflaging a for loop in a while loop, you make the poor guy cry.




I would just like to point out that this is almost exactly backwards. Using a while loop here would be emulating a for loop, not the other way around. I still see a lot of people espousing the antiquated C coding standards that say not to use a break in a for loop, but they are just that; outdated. The only time you will ever know at runtime how many times a for loop will be executed is if you use a constant value in a conditional test.

Obviously the preferable method here would be to use an algorithm like std::find_if as another poster mentioned. But absent that, a for loop is a better option than a while loop. Indeed, std::find_if itself is typically implemented as a for loop with a break, i.e.:


// TEMPLATE FUNCTION find_if
template<class _InIt, class _Pr> inline
_InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{
// find first satisfying _Pred
for (; _First != _Last; ++_First)
if (_Pred(*_First))
break;
return (_First);
}

This topic is closed to new replies.

Advertisement