Link to home
Start Free TrialLog in
Avatar of Rugoingwme
Rugoingwme

asked on

specific uses of variable and function names in a constructor in C++

Hi,

I'm a newbie programmer trying to learn C++ from a book. My questions are around the use of constructors.  The relevant code below is from code listing in the book I am using to learn C++.  The relevant code is as follows (I am not including the brake and pedal functions in the interest of brevity):

#include <iostream>

class Tricycle
{
public:            
      int getSpeed();
      void setSpeed(int speed);
      Tricycle(int initialAge);
      ~Tricycle();  
      void pedal();
      void brake();
private:      
      int speed;

};
//  48----------------------------------------------------------------------------------------------
// use constructor to set bike's initial speed

Tricycle::Tricycle(int startSpeed)  
{
      setSpeed(startSpeed);
}

int main()
{
      Tricycle wichita(27);

      wichita.pedal();
      wichita.pedal();
      wichita.pedal();
      wichita.brake();

The above code compiled and worked with no problems.  But I don't understand why did the Tricycle wichita(27) work, when there was only the reference to the Tricycle class in the line "Tricycle wichita(27)". I understand that the Tricycle class has a private variable named
"int speed;", and a public function called "int setSpeed()", but the constructor is defined as

 Tricycle::Tricycle(int initialSpeed)
 {
      setSpeed(initialSpeed);
 }
 so my real confusion is around why setSpeed(initialSpeed) is the same as void setSpeed(int speed). is it because the setSpeed() function is overloaded? (if it is, the book doesn't make that point).

Then, if its ok that the function is overloaded, why does in main(), Tricycle wichita(27) work, when Tricycle wichita says nothing about setSpeed? Is it because the Constructor creates an object for setting the initial speed at the class level (Tricycle)?
or is it that any object using the class Tricycle gets the object created for it automatically using whatever value is in setSpeed as its initial value?  
It's as if you created a object that gave the entire class a value (Tricycle ...(27)).

What if i had created 20 different constructors, how would Tricycle wichita know
which constructor applied?

Thanks for any help!


ASKER CERTIFIED SOLUTION
Avatar of strickdd
strickdd
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
check for this pointer
>> I'm a newbie programmer trying to learn C++ from a book

A little off topic (so please do not award this any points) but...

If you're book is teaching you to initialise class member variables in this way I'd throw it out and get a better book! Initialising a class member indirectly in the constructor via a setter function is (except for in special cases -- such as needing to perform validation on input values) a generally poor way to handle member initialisation. It's inefficient because the member effectively gets assign a value twice. The properly way to do this is via a constructor initialisation list.

One could argue (as I'm sure the author would) that this is a more advanced topic. To that I say poppy-kook! That way of teaching C++ is basically showing you the bad way to do things and then expecting you to re-learn the correct way of doing things. This is generally the reason so many new C++ programmers either struggle or don't even know about such things exist.

The same poor approach is taken with const-correctness. Authors avoid explaining about making code const correct early on because it adds to the learning curve but what happens is you learn to code without thinking about constness and that habit sticks. Then, when you start working with code written by someone who does know how to write cost correct code your code then won't compile and you have no idea why.

Sorry to rant but it frustrates me when I see someone trying to learn from bad teaching material.

FWIW, if the author was teaching you properly then the code would look more like this...



class Tricycle
{
public:            
      Tricycle(int speed); 
      ~Tricycle();  

      int getSpeed() const; // since this is a getter is should almost certainly be const
      void setSpeed(int speed);

      void pedal();
      void brake();
private:      
      int speed_; // conventionally member vars start with m_ or end with _ (I prefer the latter)
};

Tricycle::Tricycle(int speed) 
   : speed_(speed) // initialised using a constructor initialiser
{
}

int main()
{
      Tricycle wichita(27); // constructing a Tricycle with an initial speed of 27

      wichita.pedal();
      wichita.pedal();
      wichita.pedal();
      wichita.brake();
}

Open in new window

Avatar of stachenov
stachenov

>> It's inefficient because the member effectively gets assign a value twice.

Why twice? One time in the setSpeed(), another in...? Nowhere? After all, if you don't call setSpeed(), it isn't initialized at all. On the other hand, if setSpeed() has some useful side effects, it would be more consistent to call it rather than replicate that side effects in the constructor. In all constructors, in fact, since C++ doesn't have constructor chaining.
>> Why twice?

Um, did you bother to read the link I provided? Do you understand how a class gets constructed, what happens and when? If you do then you'd understand why it's inefficient. The fact you don't means you're making an assertion based on your own naive assumption rather than understanding what actually happens.

In the case of an intrinsic the constructor isn't called implicitly but for all other types the compiler will call the member objects constructor. So, the first time is when the member is constructed and the second time is when the assignment is performed. By using a member initialisation list you initialise the member through its constructor rather than post construction via its assignment operator.

>> it would be more consistent to call it rather than replicate that side effects in the constructor

It is also hugely inefficient -- it may not be that big of a deal for an intrinsic type but it is a big deal when it is a composite object.
Avatar of Rugoingwme

ASKER

guys,  thanks for your patience.  I'm in the middle of traveling.  And thanks for the replies.  Overall, I understand most of the explanations to move on to other programming agonies.

Evilrix: Yeah, the only reason I bought the book i'm using is because Barnes & Noble only had this version available in the store, and I couldn't order the books online that I wanted that were rated good by users .