By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,465 Members | 1,480 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,465 IT Pros & Developers. It's quick & easy.

Not calling base class constructors

P: n/a
I've noticed that when constructing a subclass, the base class get's
it's contructors called.

Is there some way to avoid this? The base class has one variable, which
gets initialised to 0.

The subclass's constructor sets this variable to a real value.

So first the variable is set to 0, the variable is never used before it
once again gets set to a real value. It's a waste. Any ideas anyone?

Nov 22 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a

<st******@hotmail.com> wrote in message
news:11*********************@g43g2000cwa.googlegro ups.com...
I've noticed that when constructing a subclass, the base class get's
it's contructors called.

Is there some way to avoid this? The base class has one variable, which
gets initialised to 0.

The subclass's constructor sets this variable to a real value.

So first the variable is set to 0, the variable is never used before it
once again gets set to a real value. It's a waste. Any ideas anyone?

You could try something similar to following:

class Base {
int mem;
public:
Base(int val = 0) : mem(val) {}
};

class Derived : public Base {
public:
Derived(int a = 0) : Base(a) {}
};

Regards,
Sumit.
--
Sumit Rajan <su****@msdc.hcltech.com>

Regards,
Sumit.
--
Sumit Rajan su****@msdc.hcltech.com
Nov 22 '05 #2

P: n/a

st******@hotmail.com wrote:
I've noticed that when constructing a subclass, the base class get's
it's contructors called.
Yes, that is supposed to happen as the base is instantiated before the
derived.

Is there some way to avoid this? The base class has one variable, which
gets initialised to 0.
No.

The subclass's constructor sets this variable to a real value.
Why does the base class constructor not set it? How does the derived
class set it - with a setter, I hope. We don't want protected members
:-).

So first the variable is set to 0, the variable is never used before it
once again gets set to a real value. It's a waste. Any ideas anyone?


Initialise it by forwarding the parameter to the base constructor.

class Base
{
public:
explicit Base(int mem): mem_( mem ){ ; }
//The rest of bases interface...omitted - perhaps includes
// virtual ~Base, depending on whether want to delete
// via Base.
int getMem() const;
void setMem();

private:
int mem_;
};

class Derived : public Base
{
public:
explicit Derived( int mem ): Base( mem ){}
//etc...
};

Nov 22 '05 #3

P: n/a
OK I'd like it to work like this:

GenericObject obj; // internal member is 0.
StringObject str = "hello world"; // string object is a subclass of
GenericObject

So basically, StringObject needs to be constructed via the constructor
and not via a setter. Otherwise it will be awkward.

However doing this will set it's internal member twice, once to 0 and
then the second time to a real pointer.

Nov 22 '05 #4

P: n/a
st******@hotmail.com wrote:
OK I'd like it to work like this:

GenericObject obj; // internal member is 0.
StringObject str = "hello world"; // string object is a subclass of
GenericObject

So basically, StringObject needs to be constructed via the constructor
and not via a setter. Otherwise it will be awkward.

However doing this will set it's internal member twice, once to 0 and
then the second time to a real pointer.


First, have you shown with a profiler that this is really an issue? It
sounds to me like you are worried about something that probably doesn't
matter and are prematurely optimizing. Are you sure that your optimizer
doesn't strip the first initialization anyway?

Second, can you use the solution mentioned by Sumit and werasm? It
would only initialize the parameter once.

Cheers! --M

Nov 22 '05 #5

P: n/a
st******@hotmail.com wrote:
OK I'd like it to work like this:

GenericObject obj; // internal member is 0.
StringObject str = "hello world"; // string object is a subclass of
GenericObject

So basically, StringObject needs to be constructed via the constructor
and not via a setter. Otherwise it will be awkward.

However doing this will set it's internal member twice, once to 0 and
then the second time to a real pointer.


You have to provide more details. What "internal member" you are talking about?
Is that the member intended to store the pointer to the string in the
'StringObject'? If that's the case, then why is that "internal member" declared
as high in the class hierarchy as 'GenericObject'? Or is it something else?

--
Best regards,
Andrey Tarasevich
Nov 22 '05 #6

P: n/a
st******@hotmail.com wrote:
OK I'd like it to work like this:

GenericObject obj; // internal member is 0.
StringObject str = "hello world"; // string object is a subclass of
GenericObject

So basically, StringObject needs to be constructed via the constructor
and not via a setter. Otherwise it will be awkward.

However doing this will set it's internal member twice, once to 0 and
then the second time to a real pointer.


class GenericObject
{
public:
GenericObject() : internal_member(0) {}
GenericObject(const void* ptr) : internal_member(ptr) {}
};

class StringObject : public GenericObject
{
public:
StringObject(const char* str) : GenericObject(str) {}
};

What's is the problem with this solution? Answering this will perhaps
help solve your real problem.

john
Nov 22 '05 #7

P: n/a
>
class GenericObject
{
public:
GenericObject() : internal_member(0) {}
GenericObject(const void* ptr) : internal_member(ptr) {}
private:
const void* internal_member; };


I meant this of course.

John
Nov 22 '05 #8

P: n/a
I don't have a problem with the solution in the sense that I am against
it.

however, I am unsure of how it works.

class StringObject : public GenericObject
{
public:
StringObject(const char* str) : GenericObject(str) {}
};

To me, that looks like GenericObject() will be called, twice.

Think about it:

StringObject(const char* str) {
; // no code here
}

This constructor will actually still allow the base class's constructor
to be called, right?
StringObject(const char* str) : member(SomeFunction(str)) {
; // no code here
}

This constructor first gets it's internal member set to 0, and then set
to the result of SomeFunction.

So by explicitly calling the base class's constructor function, isn't
the base constructor being called twice?

Or is there some sort of self-inconsistancy in C++ specifically
designed to say that if you specifiy the base class's constructor
within the initialisor, it doesn't get called twice? If so, what are
the limits to this rule? If you call the constructor twice within the
initiailiser does it still get called once, or twice?

What if you call a base constructor in the initialiser that has a
different signiture than our derived class's constructor? Does the
base's constructor still only get called once or twice?

I'm just rather new to C++'s details.

Nov 22 '05 #9

P: n/a

st******@hotmail.com wrote:
OK I'd like it to work like this:

GenericObject obj; // internal member is 0.
StringObject str = "hello world"; // string object is a subclass of
GenericObject

So basically, StringObject needs to be constructed via the constructor
and not via a setter. Otherwise it will be awkward.
Usually ABC's (Abstract Base Classes) or interfaces (which is mostly
why you require inheritance) are accessed via pointer or reference.
Your example here above is a little skimpy to comment, but the fact
that you have implementation in your Base is dubious already.

However doing this will set it's internal member twice, once to 0 and
then the second time to a real pointer.

This is not true, there is only on member and it is only set once - as
the example showed. Besides, even if there were to, as someone else
already stated - std::string uses copy on write semantics - chances are
that there would very little overhead regardless as memory between two
strings in case below...

std::string s1( "Hallo World" );
std::string s2( s1 );

.... is shared - if s1 goes out of scope before s2, then s2 will
effectively own the contents of the string created by s1.

string s2;
//begin scope
{
string s1( "Hallo world." );
s2 = s1;

}//end scope

//At this point, chances are quite good that s2 now
// owns the memory originally created by s1 due to COW.

Give us a better example :0

GenericObject obj; // internal member is 0.
??? Why do you instantiate generic object, weird and suspect.

StringObject str = "hello world"; // string object is a subclass of
As StringObject inherits (publicly) from GenericObject, it <is a>
GenericObject, therefore the GenericObject member (that forms
part of StringObject) is initialised. No need to instantiate generic
object explicitly

GenericObject ??? What - this is invalid/meaningless code/example

Regards,

W

Nov 22 '05 #10

P: n/a
st******@hotmail.com wrote:

I don't have a problem with the solution in the sense that I am against
it.

however, I am unsure of how it works.

class StringObject : public GenericObject
{
public:
StringObject(const char* str) : GenericObject(str) {}
};

To me, that looks like GenericObject() will be called, twice.
It isn't.

While the abover looks like a function call, it isn't one.
The compiler calls the base class constructor for you in any
case. But here you can specify which one to use, just in case
there are more then one to choose from; or/and you have the
ability to pass arguments to the choosen constructor.


Think about it:

StringObject(const char* str) {
; // no code here
}

This constructor will actually still allow the base class's constructor
to be called, right?
Yes. If you don't specify which one to use, the compiler always
uses the so called default constructor.

StringObject(const char* str) : member(SomeFunction(str)) {
; // no code here
}

This constructor first gets it's internal member set to 0, and then set
to the result of SomeFunction.
No.
The compiler will choose a constructor for member, which allows passing
the result of SomeFuntion() to it.

So by explicitly calling the base class's constructor function, isn't
the base constructor being called twice?


You don't call the base class constructor explicite. You can't call
a constructor, since it is not an ordinary function (I know, Alf.
Please do me a favour don't respond to this).

But you can specify *which* constructor, out of many you want the compiler
to choose and you can pass arguments when doing so.

Summary:
A base class constructor is called in any case. But you have the oportunity
to guide the compiler which one it should be.

--
Karl Heinz Buchegger
kb******@gascad.at
Nov 22 '05 #11

P: n/a
Sorry, here it is again (hopefully) without typos...
OK I'd like it to work like this: GenericObject obj; // internal member is 0.
StringObject str = "hello world"; // string object is a subclass of
GenericObject
So basically, StringObject needs to be constructed via the constructor
and not via a setter. Otherwise it will be awkward.
Usually ABC's (Abstract Base Classes) or interfaces (which is mostly
why you require inheritance) are accessed via pointer or reference.
Your example here above is a little skimpy to comment, but the fact
that you have implementation in your Base is dubious already.
However doing this will set it's internal member twice, once to 0 and
then the second time to a real pointer.

This is not true, there is only one member and it is only set once - as

the example showed. Besides, even if there were two, as someone else
already stated, std::string uses copy on write (COW) semantics. Chances
are
that there would be very little overhead regardless, as memory between
two
strings in case below...

std::string s1( "Hallo World" );
std::string s2( s1 );
.... is shared - if s1 goes out of scope before s2, then s2 will
effectively own the contents of the string created by s1.

//e.g.
string s2;
//begin scope
{
string s1( "Hallo world." );
s2 = s1;

}//end scope

//At this point, chances are quite good that s2 now
// owns the memory originally created by s1 due to COW.

//end e.g.

I must state that this behaviour is only applicable to strings because
they are implemented that way (with COW semantics). You cannot assume
this for all types having dynamic memory (incase you did not know :-)
).

Furthermore ...

Give us a better example :0. Given your original example (by line):

GenericObject obj; // internal member is 0.
??? Why do you instantiate GenericObject, weird and suspect.
....
- Remember, instantiating the derived automatically first instantiates
the base.

StringObject str = "hello world"; // string object is a subclass of
....
As StringObject inherits (publicly) from GenericObject, it <is a>
GenericObject, therefore the GenericObject member (that forms
part of StringObject) is initialised. No need to instantiate generic
object explicitly.
GenericObject ??? What - this is invalid/meaningless code/example

Regards,

Werner

Nov 22 '05 #12

P: n/a
st******@hotmail.com wrote:
I've noticed that when constructing a subclass, the base class get's
it's contructors called.

Is there some way to avoid this? The base class has one variable, which
gets initialised to 0.

The subclass's constructor sets this variable to a real value.

So first the variable is set to 0, the variable is never used before it
once again gets set to a real value. It's a waste. Any ideas anyone?


The solution is to design the base class for inheritance. When you are
designing a class to be used as a base class, you have to create
intelligent constructors that will be useful for the derived class
authors.

That way you don't have to assign to a member variable after the base
class constructor runs: you invoke the right base class constructor
where you can pass down the value that will go into that variable.
class Base {
protected:
int x, y;

Base(int xv, int yv);
public:
Base();
};

In this class, there is a public default constructor for the world to
use. It initializes the protected members x and y with some default
values. The member variables are not accessible from the outside.

But, a derived class has access to x and y. This is deliberately so.
And for that reason, a constructor is provided which initializes x and
y. The derived class authors might want different initial values for
these variables, and not the defaults that are set up in the default
constructor used by the rest of the world, so in the derived class:
class Derived : public Base {
public:
// initialize members x and y with 40 and 50
Derived() : Base(40, 50) { /* ... */ }
};

You call the base class constructor from the derived one using the
above syntax in the initializer list.

In general, you have to be quite flexible about initialization. If your
initialization is too encapsulated, life is difficult for derived class
writers: they have to allow your default initializations to occur, and
then mutate the object in various ways. Sometimes, those extra steps
can be quite expensive.

Imagine a GUI object which sets up a whole ton of defaults by calling
the window system. The derived object then has to make a whole ton of
more calls to override those defaults.

E.g. suppose a text widget object creates a default font. It calls the
GUI framework to search for the font by name, size, boldness, and other
attributes. It constructs the font object and retains the handle, etc.
Then, the derived class wants a different default font. Oops! So we
deallocate that one, and do it all over again ... It could all be
avoided by taking the font parameters through the constructor, or
providing two-step initialization.

Nov 22 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.