Matching Parameter Names to Class Fields

Started by
17 comments, last by l0calh05t 8 years, 7 months ago

One issue I frequently run into is trying to come up with decent names for parameter names. This is especially a problem in constructors and setter methods. For example, take the following class:


class Car
{
private:
	unsigned int gas;
	unsigned int tankCapacity;
	float headlightRange;

public:
	Car(const int& gas, const int& tankCapacity, const float& headlightRange = 15.0f) :
		gas(gas), tankCapacity(tankCapacity), headlightRange(headlightRange) { }

	void SetGas(const unsigned int& amount)
	{
		gas = amount;
		if(gas > tankCapacity)
			gas = tankCapacity;
	}

	void SetCapacity(const unsigned int& amount)
	{
		tankCapacity = amount;
		if(gas > tankCapacity)
			gas = tankCapacity;
	}

	void SetHeadlightRange(const float& range)
	{
		if(range > 0.0f)
			headlightRange = 0.0f;
	}
};

Ok, so I couldn't come up with any setters where I could only think of a parameter name that matches the field that'd I'd be modifying right now, but it's been an issue for me from time to time. Still, the constructor's a concern.

Advertisement
It's fine. Just use "this->name = name" so you don't try to assign the parameter to itself:

Car::Car(int gas, int tank_capacity, float headlight_range) {
    this->gas = gas;
    setCapacity(tank_capacity);
    setHeadlightRange(headlight_range);
}
The only problem here is your passing of POD types by const reference.

I like to prefix all class member variables with "m" which happens to avoid this issue and make it clearer which variables are member variables. I believe the "m_" prefix is the most common (based on what ive seen), Im just too lazy to type the underscore. Like how some people start all their class names with "C" (I just use capital first letter for classes and nothing else).

o3o

Naming conventions can help here.

It is often customary for member variables to have a prefix of some kind which helps reduce the problem. I've seen m, m_, _, and assorted similar prefixes in various corporate code standards. When writing code there are some slight benefits, such as knowing the variable outlives the scope of the function.

If it still conflicts, you can use this->memberVariable to access them. Major modern compilers will optimize away the pointer dereference.


const float& headlightRange = 15.0f
I am sure this isn't allowed to be const or a reference as it has a default value

If your declaration and definition are separated, i.e. you have a .h and .cpp file, you can use a different name in your definition like gasIn or gasArg while still having declared it as gas.


const float& headlightRange = 15.0f
I am sure this isn't allowed to be const or a reference as it has a default value

That is perfectly valid c++ code.

It would be better if it wasn't a const reference but a plain float, but both are valid.

devstropo.blogspot.com - Random stuff about my gamedev hobby


It's fine. Just use "this->name = name" so you don't try to assign the parameter to itself:

I use "this->" when I have identical names. When assigning variables in the constructor's initializer list, it seems to not make any different that my constructor parameters have identical names to my


The only problem here is your passing of POD types by const reference.

Do class fields still get assigned by value when passing by reference, right? One thing that confuses me about references is that I can still pass literals in as parameters. I've just recently started using references, so it's practice at this point. If I wanted to pass objects by value into my constructor (aka, make a copy, just like push_back() does in std::vector), would I not use a reference? If I wanted to pass by reference, would it be wise to use references over pointers, or does it depend on the situation?


I like to prefix all class member variables with "m" which happens to avoid this issue and make it clearer which variables are member variables. I believe the "m_" prefix is the most common (based on what ive seen), Im just too lazy to type the underscore. Like how some people start all their class names with "C" (I just use capital first letter for classes and nothing else).

I've seen these cases a lot myself in the past. I think the book, Clean Code, suggests not doing this though. I can't remember if I really read that a year ago when I read the book, or even why that'd be the case. Personally, a prefix sounds like a good way to go as, you like said, explicitly establishes scope for that variable throughout the class. I could even have local variables with the same name, but no prefix, and the code wouldn't look as confusing, provided the situation would require a variable named like that. I'm a big fan of just the preceding underscore, which appears to be a common convention in Obj-C, C#, etc. I've been told by a lead developer in the past that a preceding underscore isn't a good practice in C++ while it is in C#.

@Gooey: The code compiled fine, but it does look misleading. I didn't even think about this as I was still thinking in terms of passing-by-value. Trying to go with references over value when I can do that. but you also bring up a good point. A const reference makes it misleading.

@Strewya: Good point on the code convention. Removing the const reference sounds like the better way to go.

EDIT: I found this post on why a we shouldn't start variable names with an underscore. Bottom line: variables starting with an underscore is reserved for C++ implementors. Sounds like this goes for variables starting with both upper and lower-case letters after the underscore. Josh Petrie also pointed out in a previous post I started 2 days ago when I was doing that with my header guards. I thought he only meant that for header guards though. After reading that post, it makes all sense now. I guess m_* might be the way to go. This posts suggests using trailing underscores for naming. I kind of like that naming convention.

I've been at workplaces that have naming conventions on any incoming variables. For example, all arguments are prefixed with a. (so aGas, aCapacity, etc)

Naming convention is essential to have a good API, it informs correctly of what the function will do and where the variable is from.

Practice that as soon as possible on a coder life is the best : "Compute" if a function compute something, "Get" if a function only return something.

The prefix "Find" on a function name is nice to inform the user the function will find something and not just return something.

Always use reference only on class type if the variable is not an output of the function.

For variable of class use "m" or "m_" as prefix is a good practice.

It's common to avoid variable naming convention on math class.

This topic is closed to new replies.

Advertisement