473,407 Members | 2,676 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

Not calling base class constructors

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
12 5765

<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

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

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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Bob Hairgrove | last post by:
Consider the following: #include <string> class A { public: A( const std::string & full_name , const std::string & display_name) : m_full_name(full_name)
6
by: Justin | last post by:
Hello, first time posting. If I have a base class and a derived class, is there only one way to call the base constructor? i.e. Is this the only way I can call the base constructor...
8
by: Greg Bacchus | last post by:
I have a base class with a method that is to be called in the constructor of the inheritting classes. Is there any way of determining, say, the Type of the class that is calling it. e.g. ...
3
by: J.J. Feminella | last post by:
(Please disregard the previous message; I accidentally sent it before it was completed.) I have source code similar to the following. public class Vehicle { protected string dataV; // ......
7
by: Jo Vermeulen | last post by:
Hello, I was wondering how I could call the base class constructor from a derived class constructor. In Java I could do something like super(parameter); I tried base(parameter);
4
by: Claire | last post by:
I'm having real brain failure today. I've done this lots of times with constructors but not with virtual methods and the compiler complains because Ive put the :base(foo) after the function...
1
by: John | last post by:
Hi, Maybe someone can help me with the following: "The first task by any derived class constructor is to call it’s direct or indirect base class constructor implicitly or explicitly", reads the...
3
by: BDB | last post by:
Hi, I'm trying to call a base class' constructor. This is giving me an error: Use of keyword 'base' is not valid in this context. .... public class B : A { B( int i )
7
by: =?ISO-8859-1?Q?Fernando_G=F3mez?= | last post by:
Hello all. I have this class with a virtual method and a constructor that calls this virtual method. A derived class overrides this virtual method, so I expected that when the base's constructor is...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.