Solved

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

Posted on 2011-09-16
9
520 Views
Last Modified: 2012-05-12
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!


0
Comment
Question by:Rugoingwme
  • 2
  • 2
  • 2
  • +3
9 Comments
 
LVL 28

Accepted Solution

by:
strickdd earned 167 total points
Comment Utility
Since the method "setSpeed" has a parameter list that consists on an integer as shown in the prototype function:

void setSpeed(int speed);

You know that when calling "setSpeed" you have to pass in an integer (variable or static or constant) to the method. The method then sets the property for the initial speed.

To answer the question "how does it know which to use?" all constructors parameter list MUST be unique. When I say unique, i don't mean different variable names, but rather different variable types.

BAD:
private void doSomething(int a, int b);
private void doSomething(int d, int c); //This has the same signature as the line above and won't work

GOOD:
private void doSomething(int a, int b);
private void doSomething(string a, int b);
private void doSomething(int a, string b);
private void doSomething(string a, string b);
//All three of these methods are known as "overloads" because they are the same name, but different parameter sets.

In the "GOOD" example you will notice that all the method signatures (parameter lists) are unique. That means, when you call the method and pass in "string1" and "string2" it knows to call the 4th overload because it is the only one that accepts a string and another string.

If you pass in 1 and "string1" you will be calling the third line since you are passing in an int and then a string; however, if you pass in "string1" and 1 you end up calling the second overload because you have a string and then an int.

Order and variable types matter.
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 167 total points
Comment Utility
>> 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).

void setSpeed(int speed)  -- this instructs the compiler there will be a function called setSpeed which takes one parameter, an integer.

somewhere you will have
void Tricycle::setSpeed(int speed)
{
/// some code here
}
this is telling the compiler what the function does.


In the constructor you have the line
setSpeed(startSpeed);
this is invoking the function setSpeed from the constructor, in other words the code in setSpeed is run.

Nothing is being overloaded.  You have a declaration, a definition and a function call.  Three separate things.
0
 
LVL 4

Assisted Solution

by:stachenov
stachenov earned 166 total points
Comment Utility
"Tricycle wichita(27)" works because it is the syntax for constructing local variables. Basically it's the same as for non-class variables, but with constructor parameters added in parentheses. You're saying "I want to create a local variable of class Tricycle, this variable should be named wichita and one integer value (27) should be used as a constructor parameter". The compiler creates your variable and looks for constructors and founds one that accepts just one integer. Since it exists, it is called to initialize the variable. The constructor then calls setSpeed() to to its job, but it's irrelevant - you could just put "speed = startSpeed" in the constructor, and the effect would be the same (assuming that setSpeed() has no other side effects).

So "Tricycle wichita(27)" says nothing about "setSpeed()" because the latter is called from inside the constructor. Just like when you call any regular function, that call doesn't say anything about what happens inside the function, right?

As for your question, "why setSpeed(initialSpeed) is the same as void setSpeed(int speed)", you are confusing declaration/definition/prototype with function call. "void setSpeed(int speed)" is how function declared in the class and then defined somewhere else in the code you haven't posted. The "setSpeed(initialSpeed)" part is a call to that function, so it's not literally "the same".

There are no overloads in this example at all. Overloads are functions with the same name but different parameter lists. All of your functions have different names, so there are no overloads. If you had a "void setSpeed(double speed)" in your class, that would be an overload of "void setSpeed(int speed)". Or if you had an additional "Tricycle(int speed, bool hasWorkingBrakes)" constructor - that would be constructor overload.
0
 
LVL 9

Expert Comment

by:user_n
Comment Utility
check for this pointer
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 9

Expert Comment

by:user_n
Comment Utility
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
>> 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

0
 
LVL 4

Expert Comment

by:stachenov
Comment Utility
>> 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.
0
 
LVL 40

Expert Comment

by:evilrix
Comment Utility
>> 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.
0
 

Author Closing Comment

by:Rugoingwme
Comment Utility
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 .
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now