A question dawned on me lately: Why bother having the scope resolution operator (::) when the usage of the dot operator (.) doesn't clash with the former?
Like,
namespace my_module
{
const int insane_constant = 69;
int some_threshold = 100;
}
In order to access some_threshold, one would write my_module::some_threshold. But the thing is the left hand side of :: must be a namespace or a class, as far as I know, while that of the . can never be a namespace or a class. Moreover, the order of :: is higher than ., which is really pointless in my opinion. Why make 2 distinct operators, both of which cannot be overloaded, with use cases can be covered with just one? I'm having a hard time finding any satisfying answer, so any clue on this matter is much appriciated.
Consider the following code:
#include <iostream>
namespace my_module
{
const int insane_constant = 69;
}
class C{
public:
int insane_constant; // actually not constant, but for the example's sake
};
int main(){
C my_module;
my_module.insane_constant = my_module::insane_constant;
std::cout << my_module.insane_constant;
}
How would you distinguish my_module. from my_module:: here?
You can't replace one with the other.
Example:
namespace A
{
int x = 0;
struct X { int x = 1; } A;
void f()
{
std::cout << A.x
<< A::x
<< std::endl;
}
}
int main()
{
A::f();
}
prints "10".
Both operators have completely different purposes.
In particular, :: is for referring to a member of a scope while operator. is for referring to a member of an object.
That is, operator:: works on scope while operator. works on objects.
For instance, a classname::membername refers to the member of a class which has a class scope associated with it. On the other hand, object.membername refers to the member of the object object.
Note that not all scopes can be used with operator::. For example, we can refer to a namespace scope's member, class scopes' member(like a static member etc), enumeration' member etc using operator::.
The other answers showcase situations where :: and . do different things because they act on different entities (scopes vs objects). I'd like to add a bit of motivation behind this choice in the language by comparing it with the situation in C#. Disclaimer: I don't actually use C#, but these points seem obvious when looking into it.
In C#, the "namespace operator" is a dot ., just like the member access operator. However, you cannot have truly global variables: you need a class to put them in. In fact, you cannot even declare a class without a namespace, though this is unrelated to your question.
In C#, there is no possible ambiguity when using the dot between scope and object. Nested namespaces, classes within namespaces, class static variables, enumerators, and so on, are all accessed with a dot.
In C++, that's obviously not the case, and the language took the route of distinguishing between scopes and objects by having two distinct operators.
In plain C, there is no scope resolution, so there is no need for a :: operator. Other languages that make the distinction are Ruby and, apparently, PHP. Among languages that do not make the distinction, you can find for example Python, Go and Java. That last one does have a :: operator, but it's not for scope resolution, it's for forming method references.
In short, C++ has complex scope mechanisms because that's how the language was designed. As a result, it requires two different operators to distinguish scope access and object access.
Related
I've recently spent a lot of time with javascript and am now coming back to C++. When I'm accessing a class member from a method I feed inclined to prefix it with this->.
class Foo {
int _bar;
public:
/* ... */
void setBar(int bar) {
this->_bar = bar;
// as opposed to
_bar = bar;
}
}
On reading, it saves me a brain cycle when trying to figure out where it's coming from.
Are there any reasons I shouldn't do this?
Using this-> for class variables is perfectly acceptable.
However, don't start identifiers with an underscore, or include any identifiers with double underscore __ anywhere. There are some classes of reserved symbols that are easy to hit if you violate either of these two rules of thumb. (In particular, _IdentifierStartingWithACapital is reserved by the standard for compilers).
In principle, accessing members via this-> is a coding style that can help in making things clearer, but it seems to be a matter of taste.
However, you also seem to use prefixing members with _ (underscore). I would say that is too much, you should go for either of the two styles.
Are there any reasons I shouldn't do this?
Yes, there is a reason why you shouldn't do this.
Referencing a member variable with this-> is strictly required only when a name has been hidden, such as with:
class Foo
{
public:
void bang(int val);
int val;
};
void Foo::bang(int val)
{
val = val;
}
int main()
{
Foo foo;
foo.val = 42;
foo.bang(84);
cout << foo.val;
}
The output of this program is 42, not 84, because in bang the member variable has been hidden, and val = val results in a no-op. In this case, this-> is required:
void Foo::bang(int val)
{
this->val = val;
}
In other cases, using this-> has no effect, so it is not needed.
That, in itself, is not a reason not to use this->. The maintennance of such a program is however a reason not to use this->.
You are using this-> as a means of documentation to specify that the vairable that follows is a member variable. However, to most programmers, that's not what usign this-> actually documents. What using this-> documents is:
There is a name that's been hidden here, so I'm using a special
technique to work around that.
Since that's not what you wanted to convey, your documentation is broken.
Instead of using this-> to document that a name is a member variable, use a rational naming scheme consistently where member variables and method parameters can never be the same.
Edit Consider another illustration of the same idea.
Suppose in my codebase, you found this:
int main()
{
int(*fn)(int) = pingpong;
(fn)(42);
}
Quite an unusual construct, but being a skilled C++ programmer, you see what's happening here. fn is a pointer-to-function, and being assigned the value of pingpong, whatever that is. And then the function pointed to by pingpong is being called with the singe int value 42. So, wondering why in the world you need such a gizmo, you go looking for pingpong and find this:
static int(*pingpong)(int) = bangbang;
Ok, so what's bangbang?
int bangbang(int val)
{
cout << val;
return val+1;
}
"Now, wait a sec. What in the world is going on here? Why do we need to create a pointer-to-function and then call through that? Why not just call the function? Isn't this the same?"
int main()
{
bangbang(42);
}
Yes, it is the same. The observable effects are the same.
Wondering if that's really all there is too it, you see:
/* IMPLEMENTATION NOTE
*
* I use pointers-to-function to call free functions
* to document the difference between free functions
* and member functions.
*/
So the only reason we're using the pointer-to-function is to show that the function being called is a free function
and not a member function.
Does that seem like just a "matter of style" to you? Because it seems like insanity to me.
Here you will find:
Unless a class member name is hidden, using the class member name is equivalent to using the class member name with the this pointer and the class member access operator (->).
I think you do this backwards. You want the code to assure you that what happens is exactly what is expected.
Why add extra code to point out that nothing special is happening? Accessing class members in the member functions happen all the time. That's what would be expected. It would be much better to add extra info when it is not the normal things that happen.
In code like this
class Foo
{
public:
void setBar(int NewBar)
{ Bar = NewBar; }
you ask yourself - "Where could the Bar come from?".
As this is a setter in a class, what would it set if not a class member variable?! If it wasn't, then there would be a reason to add a lot of info about what's actually going on here!
Since you are already using a convention to signify that an identifer is a data member (although not one I would recommend), adding this-> is simply redundant in almost all cases.
This is a somewhat subjective question obvously. this-> seems much more python-idiomatic than C++-idiomatic. There are only a handful of cases in C++ where the leading this-> is required, dealing with names in parent template classes. In general if your code is well organized it will be obvious to the reader that it's a member or local variable (globals should just be avoided), and reducing the amount to be read may reduce complexity. Additionally you can use an optional style (I like trailing _) to indicate member variables.
It doesn't actually harm anything, but programmers experienced with OO will see it and find it odd. It's similarly surprising to see "yoda conditionals," ie if (0 == x).
I am quite new to using C++. I have handled Java and ActionScript before, but now I want to learn this powerful language. Since C++ grants the programmer the ability to explicitly use pointers, I am quite confused over the use of the arrow member operator. Here is a sample code I tried writing.
main.cpp:
#include <iostream>
#include "Arrow.h"
using namespace std;
int main()
{
Arrow object;
Arrow *pter = &object;
object.printCrap(); //Using Dot Access
pter->printCrap(); //Using Arrow Member Operator
return 0;
}
Arrow.cpp
#include <iostream>
#include "Arrow.h"
using namespace std;
Arrow::Arrow()
{
}
void Arrow::printCrap(){
cout << "Steak!" << endl;
}
In the above code, all it does is to print steak, using both methods (Dot and Arrow).
In short, in writing a real practical application using C++, when do I use the arrow notation? I’m used to using the dot notation due to my previous programming experience, but the arrow is completely new to me.
In C, a->b is precisely equivalent to (*a).b. The "arrow" notation was introduced as a convenience; accessing a member of a struct via a pointer was fairly common and the arrow notation is easier to write/type, and generally considered more readable as well.
C++ adds another wrinkle as well though: operator-> can be overloaded for a struct/class. Although fairly unusual otherwise, doing so is common (nearly required) for smart pointer classes.
That's not really unusual in itself: C++ allows the vast majority of operators to be overloaded (although some almost never should be, such as operator&&, operator|| and operator,).
What is unusual is how an overloaded operator-> is interpreted. First, although a->b looks like -> is a binary operator, when you overload it in C++, it's treated as a unary operator, so the correct signature is T::operator(), not T::operator(U) or something on that order.
The result is interpreted somewhat unusually as well. Assuming foo is an object of some type that overloads operator->, foo->bar is interpreted as meaning (f.operator->())->bar. That, in turn, restricts the return type of an overloaded operator->. Specifically, it must return either an instance of another class that also overloads operator-> (or a reference to such an object) or else it must return a pointer.
In the former case, a simple-looking foo->bar could actually mean "chasing" through an entire (arbitrarily long) chain of instances of objects, each of which overloads operator->, until one is finally reached that can refer to a member named bar. For an (admittedly extreme) example, consider this:
#include <iostream>
class int_proxy {
int val;
public:
int_proxy(): val(0) {}
int_proxy &operator=(int n) {
std::cout<<"int_proxy::operator= called\n";
val=n;
return *this;
}
};
struct fubar {
int_proxy bar;
} instance;
struct h {
fubar *operator->() {
std::cout<<"used h::operator->\n";
return &instance;
}
};
struct g {
h operator->() {
std::cout<<"used g::operator->\n";
return h();
}
};
struct f {
g operator->() {
std::cout<<"Used f::operator->\n";
return g();
}
};
int main() {
f foo;
foo->bar=1;
}
Even though foo->bar=1; looks like a simple assignment to a member via a pointer, this program actually produces the following output:
Used f::operator->
used g::operator->
used h::operator->
int_proxy::operator= called
Clearly, in this case foo->bar is not (even close to) equivalent to a simple (*foo).bar. As is obvious from the output, the compiler generates "hidden" code to walk through the whole series of overloaded -> operators in various classes to get from foo to (a pointer to) something that has a member named bar (which in this case is also a type that overloads operator=, so we can see output from the assignment as well).
Good Question,
Dot(.) this operator is used for accessing the member function or
sometime the data member of a class or structure using instance
variable of that class/Structure.
object.function();
object.dataMember; //not a standard for class.
arrow(->) this operator is used for accessing the member function or
sometime the data member of a class or structure but using pointer of
that class/Structure.
ptr->function();
ptr->datamember; //not a standard for class.
The -> operator is a way of calling a member function of the pointer that is being dereferenced. It can also be written as (*pter).printCap(). C++ is difficult to learn without a class or book so I recommend getting one, it'll be a great investement!
This question already has answers here:
When do I use a dot, arrow, or double colon to refer to members of a class in C++?
(4 answers)
Closed 8 years ago.
Apologies for a question that I assume is extremely basic.
I am having trouble finding out online the difference between the operator :: and . in C++
I have a few years experience with C# and Java, and am familiar with the concept of using . operator for member access.
Could anyone explain when these would be used and what the difference is?
Thanks for your time
The difference is the first is the scope resolution operator and the second is a member access syntax.
So, :: (scope resolution) can be used to access something further in a namespace like a nested class, or to access a static function. The . period operator will simply access any visible member of the class instance you're using it on.
Some examples:
class A {
public:
class B { };
static void foo() {}
void bar() {}
};
//Create instance of nested class B.
A::B myB;
//Call normal function on instance of A.
A a;
a.bar();
//Call the static function on the class (rather than on an instance of the class).
A::foo();
Note that a static function or data member is one that belongs to the class itself, whether or not you have created any instances of that class. So, if I had a static variable in my class, and crated a thousand instances of that class, there's only 1 instance of that static variable still. There would be 1000 instances of any other member that wasn't static though, one per instance of the class.
One more interesting option for when you come to it :) You'll also see:
//Create a pointer to a dynamically allocated A.
A* a = new A();
//Invoke/call bar through the pointer.
a->bar();
//Free the memory!!!
delete a;
Dynamic memory can be a little more confusing if you haven't learned it yet, so I won't go into details. Just wanted you to know that you can access members with { :: or . or -> } :)
in C++ :: is the scope resolution operator. It is used to distinguish namespaces, and static methods, basically any case you don't have an object. Where . is used to access things inside an object.
C# uses the . operator for both of them.
namespace Foo
{
public class Bar
{
public void Method()
{
}
public static void Instance()
{
}
}
}
in C# you would write code like this:
var blah = new Foo.Bar();
blah.Method();
but the equivalent C++ code would look more like this:
Foo::Bar blah;
blah.Method();
But note that the static method would also be accessed using the scope resolution operator, because you're not referencing an object.
Foo::Bar::Instance();
Where again, the C# code would only use the dot operator
Foo.Bar.Instance();
:: is for namespaces and static member access. C# uses the dot-operator for namespaces instead.
. is for non-static member access.
Not an exhaustive delineation, but it's the relevant bits that may confuse you in light of C# and Java.
For further information, see
IBM - Scope Resolution Operator
IBM - Dot Operator
:: is the scope resolution operator, so when you are resolving a scope, such as a namespace or class, you use that. For member access, you have .
The scope operator :: may be hard to understand if you don't understand namespaces or classes. A namespace is like a container for the names of various things in your code. They're generally used to disambiguate names that are common across libraries. Say both namespaces std and example have the function foobar(). So the compiler knows which function you want to use, you prepend it as either std::foobar() or example::foobar().
The :: operator can also be used when telling the compiler you want to define a function declared in a class or structure. For instance:
class foobar()
{
public:
void hello();
int number; //assume there is a constructor that sets this to 5
}
void foobar::hello()
{
cout << "Hello, world!" << endl;
}
The . operator is used when you wish to use a member of a class or structure. For instance:
foobar foo;
foo.hello();
cout << foo.number << endl;
Assuming the class is completed by writing a constructor, the output of this would be expected to be:
Hello, world!
5
You use the . operator the same in java, when accessing members of a class once its created in the program.
the :: is used in number of cases:
When you define a method in the .h/.cpp of a certain class, write
class::methodName()
either for prototyping it, or implementing it.
Also, if you don't explicitly state what namespace you use, you'd have to to use it
std::cout << "This is the output";
instead of just using cout << "This is the output;
Maybe there are more, but i don't remember right now, my C++ is a bit rusty.
In C++, :: is for identifying scope. This can mean namespace scope or class scope.
Eg.
int x;
namespace N {
int x;
struct foo {
static double x;
double y;
};
struct bar: public foo {
double y;
};
}
int main()
{
int x; // we have a local, hiding the global name
x = ::x; // explicitly identify the x in global scope
x += N::x; // explicitly identify the x in namespace N
N::foo::x = x; // set the static member of foo to our local integer
N::foo f;
f.y = f.x; // the static member is implicitly scoped by the object
f.y += N::foo::x; // or explicitly scoped
N::bar b;
assert(b.x == N::foo::x); // this static member is inherited
b.y = b.x; // we get N::bar::y by default
b.N::foo::y = b.y; // explicitly request the hidden inherited one
}
// we need to define the storage for that static somewhere too ...
int N::foo::x (0.0);
(I know what the scope resolution operator does, and how and when to use it.)
Why does C++ have the :: operator, instead of using the . operator for this purpose? Java doesn't have a separate operator, and works fine. Is there some difference between C++ and Java that means C++ requires a separate operator in order to be parsable?
My only guess is that :: is needed for precedence reasons, but I can't think why it needs to have higher precedence than, say, .. The only situation I can think it would is so that something like
a.b::c;
would be parsed as
a.(b::c);
, but I can't think of any situation in which syntax like this would be legal anyway.
Maybe it's just a case of "they do different things, so they might as well look different". But that doesn't explain why :: has higher precedence than ..
Because someone in the C++ standards committee thought that it was a good idea to allow this code to work:
struct foo
{
int blah;
};
struct thingy
{
int data;
};
struct bar : public foo
{
thingy foo;
};
int main()
{
bar test;
test.foo.data = 5;
test.foo::blah = 10;
return 0;
}
Basically, it allows a member variable and a derived class type to have the same name. I have no idea what someone was smoking when they thought that this was important. But there it is.
When the compiler sees ., it knows that the thing to the left must be an object. When it sees ::, it must be a typename or namespace (or nothing, indicating the global namespace). That's how it resolves this ambiguity.
Why C++ doesn't use . where it uses ::, is because this is how the language is defined. One plausible reason could be, to refer to the global namespace using the syntax ::a as shown below:
int a = 10;
namespace M
{
int a = 20;
namespace N
{
int a = 30;
void f()
{
int x = a; //a refers to the name inside N, same as M::N::a
int y = M::a; //M::a refers to the name inside M
int z = ::a; //::a refers to the name in the global namespace
std::cout<< x <<","<< y <<","<< z <<std::endl; //30,20,10
}
}
}
Online Demo
I don't know how Java solves this. I don't even know if in Java there is global namespace. In C#, you refer to global name using the syntax global::a, which means even C# has :: operator.
but I can't think of any situation in which syntax like this would be legal anyway.
Who said syntax like a.b::c is not legal?
Consider these classes:
struct A
{
void f() { std::cout << "A::f()" << std::endl; }
};
struct B : A
{
void f(int) { std::cout << "B::f(int)" << std::endl; }
};
Now see this (ideone):
B b;
b.f(10); //ok
b.f(); //error - as the function is hidden
b.f() cannot be called like that, as the function is hidden, and the GCC gives this error message:
error: no matching function for call to ‘B::f()’
In order to call b.f() (or rather A::f()), you need scope resolution operator:
b.A::f(); //ok - explicitly selecting the hidden function using scope resolution
Demo at ideone
Why does C++ have the :: operator, instead of using the . operator for this purpose?
The reason is given by Stroustrup himself:
In C with Classes, a dot was used to express membership of a class as well as expressing selection of a member of a particular object.
This had been the cause of some minor confusion and could also be used to construct ambiguous examples. To alleviate this, :: was introduced to mean membership of class and . was retained exclusively for membership of object
(Bjarne Stroustrup A History of C++: 1979−1991 page 21 - § 3.3.1)
Moreover it's true that
they do different things, so they might as well look different
indeed
In N::m neither N nor m are expressions with values; N and m are names known to the compiler and :: performs a (compile time) scope resolution rather than an expression evaluation. One could imagine allowing overloading of x::y where x is an object rather than a namespace or a class, but that would - contrary to first appearances - involve introducing new syntax (to allow expr::expr). It is not obvious what benefits such a complication would bring.
Operator . (dot) could in principle be overloaded using the same technique as used for ->.
(Bjarne Stroustrup's C++ Style and Technique FAQ)
Unlike Java, C++ has multiple inheritance. Here is one example where scope resolution of the kind you're talking about becomes important:
#include <iostream>
using namespace std;
struct a
{
int x;
};
struct b
{
int x;
};
struct c : public a, public b
{
::a a;
::b b;
};
int main() {
c v;
v.a::x = 5;
v.a.x = 55;
v.b::x = 6;
v.b.x = 66;
cout << v.a::x << " " << v.b::x << endl;
cout << v.a.x << " " << v.b.x << endl;
return 0;
}
Just to answer the final bit of the question about operator precedence:
class A {
public:
char A;
};
class B : public A {
public:
double A;
};
int main(int c, char** v)
{
B myB;
myB.A = 7.89;
myB.A::A = 'a';
// On the line above a hypothetical myB.A.A
// syntax would parse as (myB.A).A and since
// (myB.A) is of type double you get (double).A in the
// next step. Of course the '.' operator has no
// meaning for doubles so it causes a syntax error.
// For this reason a different operator that binds
// more strongly than '.' is needed.
return 0;
}
I always assumed C++ dot/:: usage was a style choice, to make code easier to read. As the OP writes "they do different things, so should look different."
Coming from C++, long ago, to C#, I found using only dots confusing. I was used to seeing A::doStuff(); B.doStuff();, and knowing the first is a regular function, in a namespace, and the second is a member function on instance B.
C++ is maybe my fifth language, after Basic, assembly, Pascal and Fortran, so I don't think it's first language syndrome, and I'm more a C# programmer now. But, IMHO, if you've used both, C++-style double-colon for namespaces reads better. I feel like Java/C# chose dots for both to (successfully) ease the front of the learning curve.
Scope resolution operator(::) is used to define a function outside a class or when we want to use a global variable but also has a local variable with same name.
This question already has answers here:
When should I make explicit use of the `this` pointer?
(12 answers)
Closed 6 years ago.
I'm dealing with a large code base that uses the following construct throughout
class MyClass
{
public:
void f(int x);
private:
int x;
};
void MyClass::f(int x)
{
'
'
this->x = x;
'
'
}
Personally, I'd always used and hence prefer the form
class MyClass
{
public:
void f(int x);
private:
int _x;
};
void MyClass::f(int x)
{
'
'
_x = x;
'
'
}
The reasons I prefer the latter are that it is more succinct (less code = fewer potential bugs), and that I don't like having multiple variables of the same name in scope at the same time where I can avoid it. That said, I am seeing the former usage more and more often these days. Is there any upside to second approach that I am unaware of? (e.g. effect on compile time, use with templated code, etc...) Are the advantages of either approach significant enough merit a refactor to the other? Reason I ask, that while I don't like the second approach present in the code, the amount of effort and associated risk of introducing further bugs don't quite merit a refactor.
Your version is a bit cleaner, but while you're at it, I would:
Avoid leading underscore: _x is ok until somebody chooses _MyField which is a reserved name. An initial underscore followed by a capital letter is not allowed as a variable name. See: What are the rules about using an underscore in a C++ identifier?
Make the attribute private or protected: the change is safe if it compiles, and you'll ensure your setter will be used.
The this-> story has a use, for example in templated code to make the field name dependent on your type (can solve some lookup issues).
A small example of name resolutions which are fixed by using an explicit this-> (tested with g++ 3.4.3):
#include <iostream>
#include <ostream>
class A
{
public:
int g_;
A() : g_(1) {}
const char* f() { return __FUNCTION__; }
};
const char* f() { return __FUNCTION__; }
int g_ = -1;
template < typename Base >
struct Derived : public Base
{
void print_conflicts()
{
std::cout << f() << std::endl; // Calls ::f()
std::cout << this->f() << std::endl; // Calls A::f()
std::cout << g_ << std::endl; // Prints global g_
std::cout << this->g_ << std::endl; // Prints A::g_
}
};
int main(int argc, char* argv[])
{
Derived< A >().print_conflicts();
return EXIT_SUCCESS;
}
Field naming has nothing to do with a codesmell. As Neil said, field visibility is the only codesmell here.
There are various articles regarding naming conventions in C++:
naming convention for public and private variable?
Private method naming convention
c++ namespace usage and naming rules
etc.
This usage of 'this' is encouraged by Microsoft C# coding standards. It gives a good code clarity, and is intended to be a standard over the usage of m_ or _ or anything else in member variables.
Honestly, I really dislike underscore in names anyway, I used to prefix all my members by a single 'm'.
A lot of people use this because in their IDE it will make a list of identifiers of the current class pop up.
I know I do in BCB.
I think the example you provide with the naming conflict is an exception. In Delphi though, style guidelines use a prefix (usually "a") for parameters to avoid exactly this.
My personal feeling is that fighting an existing coding convention is something you should not do. As Sutter/Alexandrescu puts it in their book 'C++ coding conventions': don't sweat the small stuff. Anyone is able to read the one or the other, whether there is a leading 'this->' or '_' or whatever.
However, consistency in naming conventions is something you typically do want, so sticking to one convention at some scope (at least file scope, ideally the entire code base, of course) is considered good practice. You mentioned that this style is used throughout a larger code base, so I think retrofitting another convention would be rather a bad idea.
If you, after all, find there is a good reason for changing it, don't do it manually. In the best case, your IDE supports these kind of 'refactorings'. Otherwise, write a script for changing it. Search & replace should be the last option. In any case, you should have a backup (source control) and some kind of automated test facility. Otherwise you won't have fun with it.
Using 'this' in this manner is IMO not a code smell, but is simply a personal preference. It is therefore not as important as consistency with the rest of the code in the system. If this code is inconsistent you could change it to match the other code. If by changing it you will introduce inconsistency with the majority of the rest of the code, that is very bad and I would leave it alone.
You don't want to ever get into a position of playing code tennis where somebody changes something purely to make it look "nice" only for somebody else to come along later with different tastes who then changes it back.
I always use the m_ naming convention. Although I dislike "Hungarian notation" in general, I find it very useful to see very clearly if I'm working with class member data. Also, I found using 2 identical variable names in the same scope too error prone.
I agree. I don't like that naming convention - I prefer one where there is an obvious distinction between member variables and local variables. What happens if you leave off the this?
class MyClass{
public:
int x;
void f(int xval);
};
//
void MyClass::f(int xval){
x = xval;
}
In my opinion this tends to add clutter to the code, so I tend to use different variable names (depending on the convention, it might be an underscore, m_, whatever).
class MyClass
{
public:
int m_x;
void f(int p_x);
};
void MyClass::f(int p_x)
{
m_x = p_x;
}
...is my preferred way using scope prefixes. m_ for member, p_ for parameter (some use a_ for argument instead), g_ for global and sometimes l_ for local if it helps readability.
If you have two variables that deserve the same name then this can help a lot and avoids having to make up some random variation on its meaning just to avoid redefinition. Or even worse, the dreaded 'x2, x3, x4, etc'...
It's more normal in C++ for members to be initialised on construction using initialiser.
To do that, you have to use a different name to the name of the member variable.
So even though I'd use Foo(int x) { this.x = x; } in Java, I wouldn't in C++.
The real smell might be the lack of use of initialisers and methods which do nothing other than mutating member variables, rather than the use of the this -> x itself.
Anyone know why it's universal practice in every C++ shop I've been in to use different names for constructor arguments to the member variables when using with initialisers? were there some C++ compilers which didn't support it?
I don't like using "this" because it's atavistic. If you're programming in good old C (remember C?), and you want to mimic some of the characteristics of OOP, you create a struct with several members (these are analogous to the properties of your object) and you create a set of functions which all take a pointer to that struct as their first argument (these are analogous to the methods of that object).
(I think this typedef syntax is correct but it's been a while...)
typedef struct _myclass
{
int _x;
} MyClass;
void f(MyClass this, int x)
{
this->_x = x;
}
In fact I believe older C++ compilers would actually compile your code to the above form and then just pass it to the C compiler. In other words -- C++ to some extent was just syntactic sugar. So I'm not sure why anyone would want to program in C++ and go back to explicitly using "this" in code -- maybe it's "syntactic Nutrisweet"
Today, most IDE editors color your variables to indicate class members of local variables. Thus, IMO, neither prefixes or 'this->' should be required for readability.
If you have a problem with naming conventions you can try to use something like the folowing.
class tea
{
public:
int cup;
int spoon;
tea(int cups, int spoons);
};
or
class tea
{
public:
int cup;
int spoon;
tea(int drink, int sugar);
};
I think you got the idea. It's basically naming the variables different but "same" in the logical sense. I hope it helps.