Need of :: to specify class for functions but not variables?

Viewed 162

Why do I need to use :: to denote if a function is a member function but I don't need to do it for the instance variables? I do understand that :: is used to differentiate between standalone and member functions, but I still don't get the variables part. I'll give an example of what I'm talking about.

Shape.h

# pragma once

class Shape {

private:
  int height;
  int width;

public:
  Shape(int height, int width);

}

Shape.cpp

#include "Shape.hpp"

Shape::Shape(int height, int width) {
  this->height = height;
  this->width = width;
}

int Shape::getHeight() {
  return height;
}

int Shape::getWidth() {
  return width;
}

Here, I have to to specify the class of the Shape constructor and the getters in order for the compiler to know what I'm talking about. So how come when I do return height; or this->height without specifying class it understands what I'm talking about.

2 Answers

C++ uses a model where it initially assumes everything is in the same namespace/class as what it's declared in unless stated otherwise. So, for example, if you write

int getHeight() {
    return height;
}

at the top level of a C++ file, the compiler assumes you're declaring something in the global namespace. That means that getHeight is a free function. Then, the statement return height; is interpreted in the context of a free function in the global namespace - it'll start searching local variables for height, then global variables in the global namespace.

On the other hand, if you write

int Shape::getHeight() {
    return height;
}

you're explicitly telling C++ "hey, I know that this code is in the global namespace at the top level, but I'm explicitly indicating that this is actually inside of the Shape class." At that point, the compiler says "ah, gotcha, you're inside Shape now" and interprets the code that's written as though it were inside Shape. In that sense, the statement return height; first starts looking for a local variable named height, then looks for a data member of Shape named height, then looks for global variables named height.

There's no fundamental reason why C++ had to do things this way, but there is a nice internal consistency to it. You stay at whatever "scope level" a statement or definition appears unless something explicitly moves you into a different scope level. So once you've declared the function in a way that says it's in Shape, everything inside it evaluates relative to Shape rather than to the global namespace.

Hope this helps!

but not variable. this is not true, you have to use :: if you want to get value outside the scope of the A class.

class A { 
    public:
        const static int a = 5;
        A (){}
};

int main (void) {
    std::cout << A::a;
}
Related