Please check out Winter

Member Discussions

terms



[Previous] [Next] [Post] [Reply] [Topics] [Summary] [Search]


1. Strange behavior with C++ virtual functions and inheritance Wed Aug 17, 2005 [10:16 AM]
Razzer_9
Email not supplied
member since: Mar 5, 2001
Reply
I recently had the weirdest problem in my C++ codebase. Hopefully someone can confirm and/or clear up my understanding here:

First, I have the two classes in question. They are like this:

class Physical {
//... code
enum update {UPDATE_POS};
virtual void Update(update u)=0;
};

class Character : public Physical, public std::iostream {
//... code
virtual void Update(update u);
};


So those are my two classes.

Now, in my MUD, I have a coordinate-based system. I was in the process of implementing movement. Players (and other things) move at a given velocity, hence the Update function handles the distance they have moved in s seconds (where s is the number of seconds since Update was last called).

Now, before I fixed my problem, I had code like this:

void Character::Update(update u)
{
//Code to decipher the constant requested
    *this << "You have finished moving." << sendl;
//sendl is similar to std::endl, but it puts "\r\n" on the
//character stream rather than just "\n"
//Rest of the code
}


The code would compile and run. However, the odd part was that I wasn't getting the string to show up on the screen. It was showing an integer which looked like a pointer value. What was even odder was that I could print out integer and floating-point constants with no problem. When I tried wrapping the string with a std::string, the compilation would fail.

After pounding my head a bit, I did this:

void Character::Update(update u)
{
//Code again
   *static_cast(this) << "You have finished moving." << sendl;
}


This compiled and worked as expected.

Frankly, I'm baffled by this. I haven't gone to my C++ standard yet to see the offical reason, but I think this is what was happening:

The Update function is in the Physical class, so the this pointer in the Update function acts more like a Physical* object rather than a std::iostream* or even a Character* object. The function lookup mechanism, therefore, doesn't look up out-of-class functions such as operator<<(const char*) or operator<<(std::string).

Is this understanding correct?


2. RE: Strange behavior with C++ virtual functions and inheritance Wed Aug 17, 2005 [11:08 AM]
Kastagaar
Email not supplied
member since: Jul 29, 1999
In Reply To
Reply
I'm trying to understand what you did, so I wrote a program which, I think, replicates your situation:
#include <iostream>

class Physical
{
public :
    enum update {UPDATE_POS};

    virtual void Update(update u) = 0;
};

class Character : public Physical, public std::iostream
{
public :
    Character() { rdbuf(std::cout.rdbuf()); }

    virtual void Update(update u);
};

void Character::Update(update u)
{
    *this << "You have finished moving.\n";
}

int main()
{
    Physical* p = new Character;
    p->Update(Physical::UPDATE_POS);
}


However, I didn't get the error you did. Perhaps you could change the above to something that fails in the manner of your program (although using << std::endl; instead of "\n" did provoke a crash, which boggles me).
There are two ways of constructing software: to make it so simple that there are obviously no errors, and to make it so complex that there are no obvious errors.


3. RE: Strange behavior with C++ virtual functions and inheritance Wed Aug 17, 2005 [11:38 AM]
Razzer_9
Email not supplied
member since: Mar 5, 2001
In Reply To
Reply
I get the same results compiling this under g++ 3.4.4. However, this is what I get under MSVC++ 7.1:

0041115CPress any key to continue

As a note, I forgot to say that I was compiling my MUD in VC++7.1 at the time.



4. RE: Strange behavior with C++ virtual functions and inheritance Wed Aug 17, 2005 [12:41 PM]
eiz
eiz@codealchemy.org
member since: Dec 24, 2002
In Reply To
Reply
(although using << std::endl; instead of "\n" did provoke a crash, which boggles me).

You aren't calling init to set up the stream.


5. RE: Strange behavior with C++ virtual functions and inheritance Wed Aug 17, 2005 [1:40 PM]
Razzer_9
Email not supplied
member since: Mar 5, 2001
In Reply To
Reply
You aren't calling init to set up the stream.

Hmm... now it works fine on g++. Still doesn't work on VC++ 7.1. Really odd.


6. RE: Strange behavior with C++ virtual functions and inheritance Fri Aug 19, 2005 [9:59 PM]
j_bellone
Email not supplied
member since: Aug 19, 2005
In Reply To
Reply
Try taking the virtual keyword off the implementation inside of the child class. You shouldn't need that there, and I believe the only reason if you should have that there is if you plan on devriving another class from that (and thus, overloading it again). You also shouldn't need to do any of that crazy static_casting on the this pointer.

(Comment added by j_bellone on Fri Aug 19 23:01:49 2005)

Bah. I didn't see what the problem was.

What does the code for the extraction operator look like ( << )? It seems you're sending an address to memory.




[Previous] [Next] [Post] [Reply] [Topics] [Summary] [Search]