Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does calling a member function as if it were static (when it's not) work in C++?

According to my understanding of C++, the following code is erroneous.

#include <iostream>

class Test {
private:
  int num_;

public:
  Test(int n) : num_(n) {}
  void printNum() { std::cout << num_ << '\n'; }
  void weird() { Test::printNum(); }
};

int main() {
  Test t(10);
  t.weird();
  return 0;
}

Test::weird() calls Test::printNum() as it would a static member function. However, Test::printNum() accesses an instance attribute and is clearly not static. Yet, the code compiles and runs to output 10.

My compiler is Apple LLVM version 7.0.0 (clang-700.1.76)

What am I missing?

like image 434
wsaleem Avatar asked Dec 27 '15 22:12

wsaleem


People also ask

Can a static function call a non-static function in C?

A static method provides NO reference to an instance of its class (it is a class method) hence, no, you cannot call a non-static method inside a static one.

Can a static function call a member function?

A static function can only access other static variables or functions present in the same class. Static member functions are called using the class name. Syntax- class_name::function_name( )

When should a member function be static?

When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member. A static member is shared by all objects of the class. All static data is initialized to zero when the first object is created, if no other initialization is present.

Why static member functions do not get this pointer?

Static member functions have two interesting quirks worth noting. First, because static member functions are not attached to an object, they have no this pointer! This makes sense when you think about it -- the this pointer always points to the object that the member function is working on.


1 Answers

What am I missing?

You're wrong about this:

Test::weird() calls Test::printNum() as a class (static) method.

It's not being called as a static method. It can't be, because it's not one.

Within a member function, you do not need an object reference or pointer (e.g. this) to call another member function. So you can write either of these:

this->printNum();
printNum();

The full name of printNum is actually Test::printNum, so you can do these too:

this->Test::printNum();
Test::printNum();

Outside of a member function, the second option in both cases is wrong because the function is not static and you did not provide an object reference or pointer.

Outside of a member function you'd also have to write the Test:: otherwise the compiler wouldn't know which printNum you're talking about, but that in itself doesn't force the call to be a "static" call. It'll be a static call iff the member function is static; period!

like image 109
Lightness Races in Orbit Avatar answered Oct 03 '22 09:10

Lightness Races in Orbit