According to the C++23 standard, what is the output of this program?
#include <iostream>
class A {};
class B {
public:
int x = 0;
};
class C : public A, B {};
struct D : private A, B {};
int main()
{
C c;
c.x = 3;
D d;
d.x = 3;
std::cout << c.x << d.x;
}The access specifiers in : private A, B / : public A, B only apply to A, not B. The implicit access specifier for B depends on how the derived class is defined.
The program has a compilation error
x is a public member of B, which is a base class of C and D. Which accessibility does x have in C and D?
If a class is declared to be a base class (§[class.derived]) for another class using the
publicaccess specifier, the public members of the base class are accessible as public members of the derived class (...). If a class is declared to be a base class for another class using theprivateaccess specifier, the public (...) members of the base class are accessible as private members of the derived class.
So any public members from A (there are none in this example) would be public in C, and private in D. But what about B, where x is defined? Are C and D deriving publicly or privately from B when there is no access-specifier?
In the absence of an access-specifier for a base class,
publicis assumed when the derived class is defined with the class-keystructandprivateis assumed when the class is defined with the class-keyclass.
So since we don't provide an access-specifier for B, class C derives privately from B, making x private. And struct D derives publicly from B, making x public.
This means the line c.x = 3 has a compilation error since x is private.