Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++ are static member functions inherited? If yes why ambiguity error does not arise?

I am just starting out with gnu-cpp and would like some help. I have come across the ambigutity error while reading and while self-study I came across this idea that static methods of a class should also be affected by the ambiguous diamond problem, but while running the following code ther is no error. Can anyone please explain why?

#include<iostream>
using namespace std;
class Base
{
  public:
  static void display(){cout<<"Static";}
};
class Derived1 : public Base {};
class Derived2 : public Base {};
class Child : public Derived1, Derived2 {};
int main(void)
{
  Child obj;
  obj.display();
}

Thank You for the help and time.

like image 414
Mudit Singal Avatar asked Feb 19 '18 11:02

Mudit Singal


People also ask

Can static function be inherited in C Plus Plus?

Quick A: Yes, and there are no ambiguity with static members.

Can static properties and static methods be inherited can it be rewritten and why?

Static methods in Java are inherited, but can not be overridden. If you declare the same method in a subclass, you hide the superclass method instead of overriding it. Static methods are not polymorphic. At the compile time, the static method will be statically linked.

What is incorrect about static member function?

Explanation: The static member functions can't be made const, since any object or class itself should be capable of making changes to the function.

Are static members inherited to subclass?

No. Static members cannot be inherited. However super class and the sub class can have static method with same signature. Super class static member will be hidden at the sub class.


3 Answers

It's fine according to the lookup rules. You see, when you write member access (obj.display();), the member display is looked up not just in the scope of the class and its base classes. Base class sub-objects are taken into consideration as well.

If the member being looked up is not static, since base class sub-objects are part of the consideration, and you have two sub-objects of the same type, there's an ambiguity in the lookup.

But when they are static, there is no ambiguity. And to make it perfectly clear, the C++ standard even has a (non-normative) example when it describes class member lookup (in the section [class.member.lookup]):

[ Note: A static member, a nested type or an enumerator defined in a base class T can unambiguously be found even if an object has more than one base class subobject of type T. Two base class subobjects share the non-static member subobjects of their common virtual base classes.  — end note ] [ Example:

struct V {
  int v;
};
struct A {
  int a;
  static int   s;
  enum { e };
};
struct B : A, virtual V { };
struct C : A, virtual V { };
struct D : B, C { };

void f(D* pd) {
  pd->v++;          // OK: only one v (virtual)
  pd->s++;          // OK: only one s (static)
  int i = pd->e;    // OK: only one e (enumerator)
  pd->a++;          // error, ambiguous: two as in D
}

 — end example ]

like image 124
StoryTeller - Unslander Monica Avatar answered Oct 10 '22 19:10

StoryTeller - Unslander Monica


The Base::display that you get via Derived1, and the Base::Display that you get via Derived2, are literally the same function. With no object context to consider (since they are static) there is no ambiguity here.

like image 4
Lightness Races in Orbit Avatar answered Oct 10 '22 20:10

Lightness Races in Orbit


Yes. It's inherited because it's a class member.

There's no ambiguity because all that's called with obj.display() is that there's only 1 candidate to be chosen, the ultimate "source" Base::display().

This code, however, generates an error:

class SuperBase {
    public:
    static void hello() { cout << "Super Base" << endl; }
};

class Base1 : public SuperBase {
    public:
    static void foo() { cout << "Base 1" << endl; }
};

class Base2 : public SuperBase {
    public:
    static void foo() { cout << "Base 2" << endl; }
};

class Derived : public Base1, public Base2 {
};

Derived obj;
obj.foo();  // Error: ambiguous resolution
obj.hello();  // No error here
like image 2
iBug Avatar answered Oct 10 '22 20:10

iBug