0
class Human {

public:

    Human(string name);
    string getName() {
        return Human::name;
    }

    void setName(string name) {
        Human::name = name ;
    }
   

private:

    string name;
};

Human::name in getName and setName funcs. work perfectly although name is not a static variable.

Why is this happening ?

As far as I know "::" is used to acces functions or static members of a class.

I thought correct usage in getName would be return this -> name or return name.

And even, when generated auto setter function in Clion, setter function uses Human::name not this -> name

I'm coming from java background and in java classname.X (which resembles classname::X in c++) was only used for static members or functions of a class. That is why I am confused

  • 2
    Plain `name` would work as well, at least for `getName()` which could just do `return name;`. Won't work in `setName` as you have another variable named `name` is a closer scope, so you need some other way to get the member variable. For example `this->name` or `Human::name`. – Some programmer dude Oct 23 '22 at 11:17
  • 2
    Also, `::` is a *scope* operator. It's not special for `static` class members, it just denotes scope. `Human::name` means "the variable `name` in the scope `Human`". – Some programmer dude Oct 23 '22 at 11:17
  • Just use "name". The rules (for all of C++) are more complicated than you think. May I recommend [a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) or two? – Jesper Juhl Oct 23 '22 at 11:18
  • 1
    https://en.cppreference.com/w/cpp/language/scope – Jesper Juhl Oct 23 '22 at 11:20
  • 1
    You're missing a return statement in `setName` so you will have **undefined behavior**. – Jason Oct 23 '22 at 11:22
  • "Inside classes" you can also refer to static members directly with the name. There is no difference to non-static members. Outside classes the Human::public_nonstatic_variable won't work obviously (static does), not because of the scope notation, but because the instance is obviously not known. – Sebastian Oct 23 '22 at 11:31
  • Thanks @Sebastian that cleared things. But still have the question, what are the differences between classname::X and this -> X. Latter uses pointer but what functionality does it add ? – theanonymous Oct 23 '22 at 17:35
  • For variables, there is no difference, which I know off. For virtual member functions, there is a difference: If you use `baseclassname::x()` in a (e.g. non-overriden) function of the base class to call a virtual (and overridden) member function `x()`, then the base class version is used, if you use `x()` or `this->x()`, the virtually overridden class is used. – Sebastian Oct 23 '22 at 19:09

2 Answers2

0

According to the C++ 17 Standard (6.4.3 Qualified name lookup)

1 The name of a class or namespace member or enumerator can be referred to after the :: scope resolution operator (8.1) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. If a :: scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that :: considers only namespaces, types, and templates whose specializations are types. If the name found does not designate a namespace or a class, enumeration, or dependent type, the program is ill-formed.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thank you! This was helpful! But still have the question, what are the differences between classname::X and this -> X. Latter uses pointer but what functionality does it add ? – theanonymous Oct 23 '22 at 17:41
0

First things first, you're missing a return statement inside setName, so the program will have undefined behavior.


Now, Human::name is a qualified name that refers to(or names) the non-static data member name. For qualified names like Human::name, qualified lookup happens which will find the data member name.

On the other hand, just name(without any qualification) is an unqualified name and so for it, unqualified lookup will happen which will also find the data member named name. And so you could have just used name(instead of Human::name) as it will also refer to the same non-static data member.


Basically the main difference between name and Human::name are that:

  1. name is a unqualified name while Human::name is a qualified name.

  2. For name unqualified lookup will happen while for Human::name qualified lookup will happen.


The similarity between the two is that:

  1. Both at the end of the day refer to the same non-static data member.
Jason
  • 36,170
  • 5
  • 26
  • 60
  • Thank you. But still have the question, what are the differences between classname::X and this -> X. Latter uses pointer but what functionality does it add ? – theanonymous Oct 23 '22 at 17:40
  • @justauser Both of `classname::X` and `this->X` are qualified names and for both of them qualified lookup will happen and again `this->x` also refers to a member named `x` of the class. – Jason Oct 23 '22 at 17:43
  • So, in terms of accessing member named x there won't be any important differences that the programmer should know right ? I'm quite new to c++ and pointers. Which one do you prefer? And I wonder why did c++ designers put these 2 diff. ways basically do the same thing ? (I'm not saying that every problem has a one way solution in syntax , just curious) – theanonymous Oct 23 '22 at 17:51
  • Sometimes(like when we're dealing with templates) we can only use `this->` but not `classname::`. For example, see [Why do I have to access template base class members through the this pointer?](https://stackoverflow.com/a/4643295/12002570). Basically when dependent names are involved the matter becomes fairly complicated and we must either use `classname::membername` or `this->membername` and just using `membername` will not work. Moreover, in some cases only one of `classname::membername` or `this->membername` works. So they are useful for in different situations. – Jason Oct 23 '22 at 17:57
  • @justauser Most C++ programmers prefer to just use the name `x` directly. Some few C++ programmers always use `this->x` to signify that it is a member variable (compared to a local variable or a function parameter). I signify this by prefixing the member variable name with an underscore, i.e. `_x` and leaving out the `this->`. (The variable starts with a lower case and it is a dependent scope, so this is allowed). Some programmers prefix member variable names with `m_`, ,i.e. `m_x`. The `class::` notation is mostly used for inheritance hierarchies, if you want to select a specific version. – Sebastian Oct 23 '22 at 19:16