Jump to content
  • Advertisement
Sign in to follow this  
Mantear

Verifying defined behavior [C++]

This topic is 3822 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Greetings, I've got a C++ code snippet that works the way I intended it to. However, I just want to verify that what it is doing is defined behavior and not just working the way I want because that's how the compiler did it. I also want to be aware of any pitfalls. Here's an example:
class Base
{
   Base() { SomeFunction(); }

   virtual void SomeFunction() { /* do 'A' */ }
};

class Derived : public Base
{
   Derived() { SomeFunction(); }

   void SomeFunction() { /* do 'B' */ }
};
In this example, the base class constructor calls SomeFunction() that performs default behavior, 'A', that most derived class will want to do. However, some derived classes will over-ride SomeFunction(). So, in the Derived class constructor, I call SomeFunction() again. This ends up calling both versions of SomeFunction(), first the Base class version then the Derived class version, which is what I want. The Base class version of SomeFunction() initializes some things to default values and the Derived class version of SomeFunction() updates those same values to be specific to the Derived class. A) Is this defined behavior? (I'm pretty sure it is) B) Is there anything wrong with what I'm doing? Thanks!

Share this post


Link to post
Share on other sites
Advertisement
It should work.

However...

Quote:
The Base class version of SomeFunction() initializes some things to default values and the Derived class version of SomeFunction() updates those same values to be specific to the Derived class


Aren't there things called constructors?


class Base {
public:
Base(x_ = 10, y_=20)
: x(x_)
, y(y_)
{}
protected:

int x;
private:
int y;

};

class Derived : public Base
{
public:
Derived( z_ = 200 )
: Base(17, 9999)
{}
private:
int z;
};



Using the above approach you follow proper RAII, and avoid multiple assignments to same variable.

BTW: if you use some dynamically allocated resources, calling some function multiple times is a nightmare to manage. One allocates, other de-allocates, neither knows about each other, yet tightly depends on it.

Share this post


Link to post
Share on other sites
Quote:

B) Is there anything wrong with what I'm doing?

Yes, see the above post. Why are you doing this? From the information you've provided, it's just a clunky, obscure, hard-to-maintain and rather poorly-designed way to mimic exactly what constructors do automatically. Except it doesn't do it as well.

I assume there's more to this?

Share this post


Link to post
Share on other sites
SomeFunction() calculates the default values for some of the member variables, I don't have default values that I can simply assign in the initialization list. I suppose I could put the calculations within the initlaization list, but I think that would look quite ugly. So I made an default initialization method in the Base class that does it for me. I made it a seperate method because there may be times that I want to re-initialize the values.

The Derived class neeeds to be able to initialize the variables to default values using different calculations specific to the Derived class. However, many of the other derived classes will just use the Base class version, not have their own version of SomeFunction(), and will not call it in their constructor.

Does that clear it up at all? Is there still a better way to do it?
Thanks.

Share this post


Link to post
Share on other sites
It sounds like Base::SomeFunction() and Derived::SomeFunction() do different things. In which case, why give them the same name? Of course, we'd be able to better comment if you showed actual code for what you were doing.

Share this post


Link to post
Share on other sites
Maybe I'm missing something, but that code shouldn't work (at least not how you expect it to). Calling a virtual function inside a constructor (or destructor) will always call the base version, so both constructors in your code call Base::SomeFunction().

Share this post


Link to post
Share on other sites
Quote:
SomeFunction() calculates the default values for some of the member variables, I don't have default values that I can simply assign in the initialization list. I suppose I could put the calculations within the initlaization list, but I think that would look quite ugly. So I made an default initialization method in the Base class that does it for me. I made it a seperate method because there may be times that I want to re-initialize the values.


I stand by my original suggestion.


struct Parameters
{
Parameters( int x, int y, int z ) {
// do some seriouz calculationz
}

Parameters( const Parameters &p ) {
: result1( p.result1 )
, result2( p.result2 )
}

var_t result1;
big_var_t result2;
};

class Base // Or, you can inherit Parameters
{
public:
Base( const Parameters &p = Parameters(10, 20, 30) )
: params( p )
{}
private:
Parameters params;

};

class Derived : public Base
{
Derived()
: Base( Parameters( -1, -1, 1 ) )
{}
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
Maybe I'm missing something, but that code shouldn't work (at least not how you expect it to). Calling a virtual function inside a constructor (or destructor) will always call the base version, so both constructors in your code call Base::SomeFunction().


No. If you have a base class Base, with a derived class Derived, calling a virtual function in a Base constructor will call the Base version, but calling it in a Derived constructor will call the Derived version. See section 12.7 paragraph 3 in the C++ Standard.

Share this post


Link to post
Share on other sites
Quote:

Original post by SiCrane
No. If you have a base class Base, with a derived class Derived, calling a virtual function in a Base constructor will call the Base version, but calling it in a Derived constructor will call the Derived version.


I just tested this and you're right (not that I was doubting you or anything [smile]).

But I do remember an issue regarding calling virtual functions in constructors. Any idea what it might be?

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
Quote:

Original post by SiCrane
No. If you have a base class Base, with a derived class Derived, calling a virtual function in a Base constructor will call the Base version, but calling it in a Derived constructor will call the Derived version.


I just tested this and you're right (not that I was doubting you or anything [smile]).

But I do remember an issue regarding calling virtual functions in constructors. Any idea what it might be?


The issue is exactly that the call in the Base constructor will call the Base version (even when it's being called indirectly by the construction of the Derived object).

More.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!