Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use identical names for fields and constructor parameters?

 class C {   T a; public:   C(T a): a(a) {;} }; 

Is it legal?

like image 704
Sergey Skoblikov Avatar asked Nov 06 '08 12:11

Sergey Skoblikov


People also ask

Can parameters have the same name?

Yes it works like this as variables of same names are allowed provided that they are in different scopes. "x" is both defined in global scope (global variable) and a local scope (in foo() as a parameter). But they are located in different locations in memory.

Can you have two constructors with the same name?

You cannot have two constructors with the exact same signature, nor two methods with the exact same signature. Parameter names do not matter.

Can a variable in a parameter list for a method have the same name as a member variable in the class?

Parameter Names The name of a parameter must be unique in its scope. It cannot be the same as the name of another parameter for the same method or constructor, and it cannot be the name of a local variable within the method or constructor. A parameter can have the same name as one of the class's fields.

Can constructors have any number of parameters?

We can have any number of Parameterized Constructor in our class. In this example, I have implemented four constructors: one is default constructor and other three are parameterized. During object creation the parameters we pass, determine which constructor should get invoked for object initialization.


2 Answers

Yes it is legal and works on all platforms. It will correctly initialize your member variable a, to the passed in value a.

It is considered by some more clean to name them differently though, but not all. I personally actually use it a lot :)

Initialization lists with the same variable name works because the syntax of an initialization item in an initialization list is as follows:

<member>(<value>)

You can verify what I wrote above by creating a simple program that does this: (It will not compile)

class  A {     A(int a)    : a(5)//<--- try to initialize a non member variable to 5    {    } }; 

You will get a compiling error something like: A does not have a field named 'a'.


On a side note:

One reason why you may not want to use the same member name as parameter name is that you would be more prone to the following:

class  A {     A(int myVarriable)    : myVariable(myVariable)//<--- Bug, there was a typo in the parameter name, myVariable will never be initialized properly    {    }    int myVariable; }; 

On a side note(2):

One reason why you may want to use the same member name as parameter name is that you would be less prone to the following:

class  A {     A(int myVariable_)    {      //<-- do something with _myVariable, oops _myVariable wasn't initialized yet      ...      _myVariable = myVariable_;    }    int _myVariable; }; 

This could also happen with large initialization lists and you use _myVariable before initializing it in the initialization list.

like image 70
Brian R. Bondy Avatar answered Oct 13 '22 14:10

Brian R. Bondy


One of the things that may lead to confusion regarding this topic is how variables are prioritized by the compiler. For example, if one of the constructor arguments has the same name as a class member you could write the following in the initialization list:

MyClass(int a) : a(a) { } 

But does the above code have the same effect as this?

MyClass(int a) {     a=a; } 

The answer is no. Whenever you type "a" inside the body of the constructor the compiler will first look for a local variable or constructor argument called "a", and only if it doesn't find one will it start looking for a class member called "a" (and if none is available it will then look for a global variable called "a", by the way). The result is that the above statment "a=a" will assign the value stored in argument "a" to argument "a" rendering it a useless statement.

In order to assign the value of the argument to the class member "a" you need to inform the compiler that you are referencing a value inside this class instance:

MyClass(int a) {     this->a=a; } 

Fine, but what if you did something like this (notice that there isn't an argument called "a"):

MyClass() : a(a) { } 

Well, in that case the compiler would first look for an argument called "a" and when it discovered that there wasn't any it would assign the value of class member "a" to class member "a", which effectively would do nothing.

Lastly you should know that you can only assign values to class members in the initialization list so the following will produce an error:

MyClass(int x) : x(100) // error: the class doesn't have a member called "x" { } 
like image 45
Dragonion Avatar answered Oct 13 '22 15:10

Dragonion