Class method and variable with same name, compile error in C++ not in Java?

Viewed 48240
class Test {

      bool isVal() const {
          return isVal;
      }

  private:

      bool isVal;
};

On Compiling this file it says

testClass.cpp:9: declaration of `bool Test::isVal'

testClass.cpp:3: conflicts with previous declaration `bool Test::isVal()'

Although the same would work for java

class Test {

  private boolean isVal;

  public boolean isVal() {
      return isVal;
  }

}

Why does the compile error occur in C++ not in Java?

7 Answers

Because C++ is not Java. You can take the address of a member:

&Test::isVal

So you can't have two members have the same name, except that you can overload member functions. Even if you could disambiguate that by some kind of cast, the next problem would already arise at other places.

In C++, a lot of people including me usually call data members specially, like putting a m before their name. This avoids the problem:

class Test {
public:
    bool IsVal() const { return mIsVal; }
private:
    bool mIsVal;
};

Functions in c/c++ are just pointers to a location in memory where the code is located, isVal (as a boolean) and isVal (as a function) are therefore ambiguous.

The quick answer is "because that's the way C++ works." C++ doesn't have a separate name space for member variables and member functions (ie, "methods") where Java (apparently, as I haven't tried this) does.

In any case, remember the old story about the guy who went to a doctor and said "Doc, it hurts when I do this." To which the doctor replied "well, don't do that!" This is a language peculiarity on its way to becoming a Dumb Programmer Trick.

Well, if you really need it, you can do it:

#include <iostream>

struct TestBase {
      bool isVal;
};

struct Test : TestBase {
      bool isVal() const {
          return TestBase::isVal;
      }
};

int main() {
  Test t;
  std::cout << static_cast<TestBase&>(t).isVal << std::endl;
  std::cout << t.isVal() << std::endl;
}

https://replit.com/@Konard/SameNameVariableAndFunction#main.cpp

This way you have members with the same name, but with different addresses. Though isVal variable is hidden by isVal function in the derived struct, you still can access this variable if you cast your struct to TestBase reference.

Related