89

If I have for example two classes A and B, such that class B inherits A as follows:

class B: public A

In this case, I'm doing public inheritance.

If I write the previous code as follows:

class B: A

What type of inheritance will I be doing here (i.e; public)? In other words, what is the default access specifier?

Just a side question here. Do I call the previous line of codes statements? Especially that I remember I read in the C++ Without Fear: A Beginner's Guide That Makes You Feel Smart book that statements are that that end with ;. What do you think about that?

Thanks.

Simplicity
  • 47,404
  • 98
  • 256
  • 385

9 Answers9

142

Just a small addition to all the existing answers: the default type of the inheritance depends on the inheriting (derived) type (B in the example), not on the one that is being inherited (base) (A in the example).

For example:

class A {};
struct B: /* public */ A {};
struct A {};
class B: /* private */ A {};
anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • 1
    I believe (at least it's what Clang does) the term is "tag" (to refer to the item which is one of class/struct/union) -- That is to say, the default inheritance type is determined by the tag type (tag kind?) of the inheriting type. – Steven Lu Apr 09 '15 at 01:35
31

It's private for class and public for struct.

Side answer: No, these are definitions of the class according to the standard. Class definition end with a semicolon. On the other hand not all statements end with a semicolon (e.g. an if statement does not).

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
7

When you inherit a class from another class (inherit class Base from class Derived in this case), then the default access specifier is private.

#include <stdio.h>

class Base {
public:
int x;
};

class Derived : Base { }; // is equilalent to class Derived : private Base       {}

int main()
{
 Derived d;
 d.x = 20; // compiler error becuase inheritance is private
 getchar();
 return 0;
}

When you inherit a class from a structure (inherit class Base from struct Derived in this case), then the default access specifier is public.

#include < stdio.h >
  class Base {
    public:
      int x;
  };

struct Derived: Base {}; // is equilalent to struct Derived : public Base {}

int main() {
  Derived d;
  d.x = 20; // works fine becuase inheritance is public
  getchar();
  return 0;
}
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
Pradip Khomane
  • 106
  • 2
  • 7
3

If you use class to define your class, the default access specifier will be private. (I think it's wrong, too.) If you use struct, however, it will be public.

And class definitions are declarations, I think. A statement is what translates into actual code (unless optimized away, anyway).
However, a mildly exotic feature of C and C++ is that expressions are statements. That's why 3+4; is a syntactically legal statement in C++ (although many compilers will warn about it having no effect). While it is obviously nonsense in this case, in general expressions are evaluated for their side effects. (An obvious example is discarding a function's return value. You call the function not to obtain a result, but for its side effects.)

sbi
  • 219,715
  • 46
  • 258
  • 445
  • "A statement is what translates into actual code" No. In C++, a typedef is a statement, and does not itself correspond to any generated code. What C++ considers to be a statement, differs from what C considers to be a statement. https://stackoverflow.com/a/49862170/ "expressions are statements" No. The semicolon operator has the effect of creating a statement from an expression, and discarding the expression's result. https://www.informit.com/articles/article.aspx?p=2472079&seqNum=4 "in general expressions are evaluated for their side effects" No. Arithmetic, for instance. – Max Barraclough Jul 08 '18 at 14:55
  • What do you think is wrong about default access specifier for classes being `private`? – Armen Michaeli Nov 08 '19 at 18:28
  • @amn: When I write a class, I put the public part atop, not the private part, because the public part is what everybody should be interested in. So I can (almost) never use the default access specifier. – sbi Jan 20 '20 at 19:01
2

The "type" of inheritance depends on how the class is defined. There are default access specifiers applied to inheritance. From the C++ standard:

[class.access.base]/2

In the absence of an access-specifier for a base class, public is assumed when the derived class is defined with the class-key struct and private is assumed when the class is defined with the class-key class. [ Example:

class B { /* ... */ };
class D1 : private B { /* ... */ };
class D2 : public B { /* ... */ };
class D3 : B { /* ... */ };             // B private by default
struct D4 : public B { /* ... */ };
struct D5 : private B { /* ... */ };
struct D6 : B { /* ... */ };            // B public by default
class D7 : protected B { /* ... */ };
struct D8 : protected B { /* ... */ };

Here B is a public base of D2, D4, and D6, a private base of D1, D3, and D5, and a protected base of D7 and D8.  — end example ]

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
1

The default type of the inheritance is private in C++.

class B:A
{};

is equivalent to

class B: private A
{};
dev
  • 649
  • 9
  • 11
  • 2
    Since the question asks for default inheritance access specifier and has not limited the domain of the question to `class`, the general answer would be to consider inheritance for `struct` as well. If the child type is a `struct`, the default type of inheritance is public. – Amir Nov 02 '17 at 08:39
1

If you do not choose an inheritance, C++ defaults to private inheritance in the same way class members default to private access for classes.

James
  • 5,355
  • 2
  • 18
  • 30
0

AS other casting problem you have

class A { virtual void test() = 0; };
class B : virtual public A { virtual void testb() {} };
class C : virtual public A { virtual void testc() {} };
class D : public B, public C {
 virtual void test() override {}
}

void main() {
   D d;
   void* v = &d;
   A* a = &d;

   ((D*)A)->test(); //OK
   ((D*)v)->test(); //undefined behavior (that call testb() in vtable logic at 1st inheritance position)
   dynamic_cast<D*>(v)->test(); //compile error cast from void* not permitted

   //resolution
   void* x = a;
   ((D*)x)->test(); //OK but as you can see, you must to store a* in x*

}
0

the default access specifier is an important differentiator between classes and structs. It is public by default for structs and private by default for classes.

Sulla
  • 7,631
  • 9
  • 45
  • 71