C++/Class

Advertisement


Question
Given the following class definition

class Tank {
    const float water_level;
    int &numfishes; };

Implement a suitable constructor that takes in appropriate parameters to initialize the data members in Tank class.

The ans. is below

Tank:: tank( float level, int &num) : water_level(level), numfishes(num) { }

Would you mind explain the ans.?

Answer
My first thought here is could you please explain which part of the answer you did not understand?

OK here goes:

In C++ objects are constructed. Construction allows user defined class types to define their initialisation behaviour in the light of various parameters and often in the light of no parameters - called default construction. They have the same name as the class they are a constructor of and have no return type. A class can have more than one constructor to allow for construction from different sets of parameter types.

In this case Tank has two private data members:

water_level, a float type
numfishes, a reference to an int type

Now the first of these, water_level, need not be explicitly initialised - it will generally contain junk in this case. However the C++ rules on initialisation of reference data members states that they _must_ be initialised in a constructor - and not only in a constructor but before the body of the constructor in its initialisation list.

So a constructor for junk should at least initialise numfishes:

class Tank
{
public:
       Tank( int & nFishes );

private:
       const float water_level;
       int &numfishes;
};

Now we can associates numfishes with some int elsewhere passed to Tank instances in its constructor. We do not allow control of setting the initial value of water_level however - so at best we can set water_level to some safe initial value such as 0.0 :

Tank::Tank( int & nFishes )
:  numfishes( nFishes )
{
}

In the above example we set numfishes to refer to the int referred to by the nFishes parameter in the initialisation list.

I should clarify that only constructors have an initialisation list and they appear after the constructor declaration and before the constructor function body. They start with a colon (':') and each item is separated with a comma (','). The items in a constructor initialiser list are either base class names or class instance members and each is initialised using the constructor-call syntax style (that is, the parameters to construct each base class or member are placed in parentheses). Note that the order that members are initialised is in the order they appear in _class_ _definition_ and _not_ the order they appear in the constructor initialisation list. Some compilers will warn you if these orders differ.

Now back to the example. I do not set an initial value for water_level at all - leaving it to be set to random junk in most cases. We could set water_level in the body of the constructor like so:

Tank::Tank( int & nFishes )
:  numfishes( nFishes )
{
       water_level = 0.0;
}

But it is better C++ style to set it also in the initialisation list for the constructor:

Tank::Tank( int & nFishes )
:  water_level( 0.0 )
,  numfishes( nFishes )
{
}

The initialisation that takes place in the initialiser list overrides the default construction of base classes and instance data members and occurs before the body of the constructor is executed. If a member or a base is not initialised in the initialiser list it will have been default constructed by this point. In our case this does not mean much as the default construction for members of built in types such a water_level does nothing, but for other member types it could mean that two sets of work are done to (for example) default initialise the member object and then assign some value to it when using an appropriate constructor could have initialised the member object to the appropriate initial value in one go.

Now it would be nice if we could also initialise a Tank to its initial water level as well. To do this we merely add a float parameter to our constructor, which in the obvious implementation gives us the answer you were enquiring about:

class Tank
{
public:
       Tank( float level, int & nFishes );

private:
       const float water_level;
       int &numfishes;
};

Tank::Tank( float level, int & nFishes )
:  water_level( level )
,  numfishes( nFishes )
{
}

If for some reason you wished to keep our original constructor then this is OK as well:

class Tank
{
public:
       Tank( int & nFishes );
       Tank( float level, int & nFishes );

private:
       const float water_level;
       int &numfishes;
};

Tank::Tank( int & nFishes )
:  water_level( 0.0 )
,  numfishes( nFishes )
{
}

Tank::Tank( float level, int & nFishes )
:  water_level( level )
,  numfishes( nFishes )
{
}

But you could make use of another C++ feature - default parameter values - and have the functionality of giving only the number of fishes integer reference or giving both the number of fishes integer reference and the water level using only one constructor:

class Tank
{
public:
       Tank( int & nFishes, float level=0.0 );

private:
       const float water_level;
       int &       numfishes;
};

Tank::Tank( int & nFishes, float level )
:  water_level( level )
,  numfishes( nFishes )
{
}

Here I have had to reverse the order of the parameters in the two parameter constructor. This is because you can only specify default values for parameters at the end of the parameter list - any parameters that require a value _must_ come before those with default values. So in this case as nFishes requires a value it must come before the level parameter which I have now specified to have the default value of 0.0.

This allows us to write:

int lots_of_fish(1000);

Tank big_tank_of_dead_fish(lots_of_fish); // no water!

And:

int lots_of_fish(1000);

Tank big_tank(lots_of_fish, 10.23);

In the first case as we did not supply the value for the level parameter the compiler checks the declaration and sees it has a default of 0.0 and plugs it into the call on our behalf.

I have given you a quick tour around constructors based on your question. If I missed what you wanted to know then I am sorry, and please ask again in a follow up or new question - as I said you did not give me much on which to focus my reply subject matter on.

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.