1

I ran into a problem, that I somehow managed to solve, but still would like to understand the language and the reasoning behind it. I have the following system of three classes:

File class_a.hpp

#pragma once

class A
{
public:
    A();
};

File class_b.hpp

#pragma once

#include "class_a.hpp"

class B : A
{
public:
    B() : A() {}

    virtual double do_something(A &with_object) const;
};

File class_c.hpp

#pragma once

#include "class_b.hpp"

class C : B
{
public:
    C() : B() {}

    double do_something(::A &with_object) const; // but differently than class B
};

Now if I was not to use the fully qualified name for the type A in the C's do_something() method, I'd get the following error still in editor:

type "A::A" (declared at line 27 of "class_a.hpp") is inaccessible C/C++(265)

What could be possible causing any ambiguity in this case? I certainly haven't redefined or used the name A as an identifier. Is there something happening in the background that makes use of the class name?

Also is the override of the do_something() method guaranteed to work this way, or is qualifying the type A in the B's method also required?

Any advice and/or pointers are also greatly appreciated!

Marty Cagas
  • 350
  • 5
  • 14

1 Answers1

1

Among other things that are inherited, there are injected-class-names. You can think of them as of hidden type aliases: class A has something like using A = A; in it, pointing to itself.

And remember that class inheritance is private by default.

Since B inherits from A privately, C can't access the contents of A, which includes A's injected-class-name.

Also is the override of the do_something() method guaranteed to work this way, or is qualifying the type A in the B's method also required?

Yes, the override in B is valid. Since B inherits from A directly, it can access all its contents, regardless of whether the inheritance is private or not.


Your code is similar to following. I replaced the injected-class-name with an actual type alias, and got the same behavior.

class A
{
  public:
    using A_type = A;
};

class B : A
{
  public:
    virtual double do_something(A_type &with_object) const;
};

class C : B
{
  public:
    double do_something(A_type &with_object) const;
};
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207