"a struct has public inheritance by default" - c++

"a struct has public inheritance by default" what does this statement really mean? And why is the following code in error just because I have omitted the keyword 'public' while deriving the class d from c??
struct c
{
protected:
int i;
public:
c(int ii=0):i(ii){}
virtual c *fun();
};
c* c::fun(){
cout<<"in c";
return &c();
}
class d : c
{
public:
d(){}
d* fun()
{
i = 9;
cout<<"in d"<<'\t'<<i;
return &d();
}
};
int main()
{
c *cc;
d dd;
cc = &dd;
cc->fun();
}

It means that
struct c;
struct d : c
is equivalent to
struct d : public c
Your code is a class extending a struct:
struct c;
class d : c;
is equivalent to
class d : private c;
because class has private inheritance by default.
And it means that all inherited and not overriden/overloaded/hidden methods from c are private in d.

"a struct has public inheritance by default" means that this
struct Derived : Base {};
is equivalent to
struct Derived : public Base {};
Classes have private inheritance by default, so when you remove the public from a class inheritance you have the equivalent of
class Derived : private Base {};
In this private inheritance scenario, Derived does not have an is-a relationship with Base, it essentially has-a Base. So the conversion you are trying to attempt here:
cc = &dd;
is not allowed.

When you write a struct and inherit from something without specifying an access specifier, that inheritance is treated as public. When you write a class and inherit from something without specifying an access specifier (even if that something is a struct), that inheritance is treated as private. In your code, you're doing the latter, so the inheritance is private, hence the observed error.
Put another way, to say that struct inheritance is public by default really means that inheritance done when writing a struct is public by default, not that inheriting from a struct is public by default.

Related

How to prevent unwanted behavior when a data member of a derived class inherits from a data member of its base class?

I have an issue with the following class structure,
class Base { int a; };
class Derived : public Base { int b; };
class OtherBase { Base c; };
class OtherDerived : public OtherBase { Derived d; };
The issue is that OtherDerived stores two instances of Base, one through the
inheritance to OtherBase and one from the inheritance to Base of the data
member d. I would like OtherDerived to store only one instance of Base.
What are the possible to achieve that while minimizing code duplication ?
One possible solution would be to use multiple inheritance:
class Base { int a; };
class Derived : public virtual Base { int b; };
class OtherBase : public virtual Base {};
class OtherDerived : public OtherBase, public Derived {};
However, here, it might not make sense for OtherBase to inherit from Base,
we might not want to present the Base interface to the user through
OtherBase.
A way to solve the issue would be to use private inheritance:
class Base { int a; };
class Derived : public virtual Base { int b; };
class OtherBase : private virtual Base {};
class OtherDerived : public OtherBase, private Derived {};
In this case, I'm wondering if it is good practice to use inheritance as a
substitute for a data member. I have been taught that inheritance of Derived
on Base should be present when “a Derived is also a Base”. In the
suggested data structure, OtherBase might not be a Base. Is my undestanding
of good practices concerning inheritance wrong or outdated ?
PS: I'm open to suggestion for an easier to read question's title.
If OtherDerived needs a Derived member, but not its Base part then there is something wrong with your design. It means that Derived is doing more than it should. Either it needs to have Base as base to be fully functional or not. It cannot be both. Use this instead:
class Base { int a; };
class Foo { int b;}
class OtherBase { Base c; };
class OtherDerived : public OtherBase { Foo d; };
And If you actually do need the original Derived elsewhere, it can be
class Derived : public Base, Foo {};

C++: multiple inheritance using virtual

Still learning basics of C++
I have a very simple query regarding the virtual keyword in multiple inheritance.
I have the following code:
class A {};
class B : public A {};
//1. class C : public A, public B {};
//2. class C : virtual public A, public B {};
//3. class C : public A, virtual public B {};
//4. class C : virtual public A, virtual public B {};
int main() {
C f;
return 0;
}
Now I know (by actually trying this code out), that 1 and 3, both cases where we do not use virtual keyword while inheriting class A work.
I understand it is the Diamond Problem of multiple inheritance, and the compiler error goes away when I inherit class A as virtual in class B:
class B: virtual public A
But I wanted to experiment with the code and removed it.
My question is, Why does creation of an object of class C fail when we inherit class A using virtual?
Note: I could not find a good article to explain in depth what this virtual keyword means and how the compiler reads it and what does the compiler do after reading the Virtual Keyword.
EDIT:
This is an experiment that I am doing, so no practical use (to me personally).
When do this:
class A {};
class B : public A {};
class C : virtual public A, virtual public B {};
int main() {
C f;
return 0;
}
Compiler throws error: error C2584: 'C': direct base 'A' is inaccessible; already a base of 'B'
even when I don't use virtual, compiler still gives the error msg as a "Warning"

Protected class inheritance in C++

The following code is giving me the error that 'A' is an inaccessible base of 'B' and I am not sure why:
class A {};
class B : protected A {};
A foo( A a );
///
B b;
foo(b);
Any explanation for this much appreciated.
Edit: I suppose I am just confused about the nature of protected inheritance. I thought it meant that any derived class (in this case of A) could inherit its variables and its functions.
A class that inherits the protected parent class can get to it, otherwise it is considered private:
class A {};
class B : protected A {};
A foo(A a) { return a; };
class C : public B {
public:
A foo(C c) { return c; };
};
int main() {
B b;
//foo(b); // Can't implicitly convert, A is protected (might as well be private from this line's perspective)
C c;
A a = c.foo(c); // class C can get A
}

how can a derived class function call a function of the base class?

Derived class function cannot access even the public members of the base class when the access specifier is private. But how is it that the function 'xyz' of my derived class able to call 'showofb'?
I even tried it by calling the function 'showofb' in the constructor of C. In both cases it works.
How is it able to call the function 'showofb' ?
class B
{
public:
B()
{
cout<<":B:"<<endl;
}
void showofb()
{
cout<<"show of b"<<endl;
}
};
class C : private B
{
public:
C()
{
cout<<":C:"<<endl;
}
void xyz()
{
showofb();
}
};
int main()
{
C c1;
c1.xyz();
}
Private inheritance inherits the public members of the parent as the private members of the child. A class can call its own or inherited private members.
Consider this:
class B
{
public:
B()
{
cout<<":B:"<<endl;
}
void showofb()
{
cout<<"show of b"<<endl;
}
};
class C : private B
{
public:
C() {}
};
class D : public B
{
public:
D(){};
}
int main()
{
C c1;
c1.showofb(); // WONT WORK
D d1;
d1.showofb(); // WILL WORK
}
B::showofb() is a public function. So it can be called by C. If you modify B to make showofb private, C will no longer be able to call it.
The private inheritance means that all public and protected members of B are inherited as private by C. So C can still call public and protected members of B, but any classes derived from C will not be able to call members of B.
user1001204, you appear to have a mistaken concept of private inheritance. That class C inherits from class B via private inheritance means that the inheritance relationship is hidden to anything that uses class C. Private inheritance does not hide the inheritance relationship inside Class C itself.

C++ Multiple Inheritance - why you no work?

I am trying to figure out an interesting multiple inheritance issue.
The grandparent is an interface class with multiple methods:
class A
{
public:
virtual int foo() = 0;
virtual int bar() = 0;
};
Then there are abstract classes that are partially completing this interface.
class B : public A
{
public:
int foo() { return 0;}
};
class C : public A
{
public:
int bar() { return 1;}
};
The class I want to use inherits from both of the parents and specifies what method should come from where via using directives:
class D : public B, public C
{
public:
using B::foo;
using C::bar;
};
When I try to instantiate a D I get errors for trying to instantiate an abstract class.
int main()
{
D d; //<-- Error cannot instantiate abstract class.
int test = d.foo();
int test2 = d.bar();
return 0;
}
Can someone help me understand the problem and how to best make use of partial implementations?
You don't have diamond inheritance. The B and C base classes of D each have their own A base class subobject because they do not inherit virtually from A.
So, in D, there are really four pure virtual member functions that need to be implemented: the A::foo and A::bar from B and the A::foo and A::bar from C.
You probably want to use virtual inheritance. The class declarations and base class lists would look like so:
class A
class B : public virtual A
class C : public virtual A
class D : public B, public C
If you don't want to use virtual inheritance then you need to override the other two pure virtual functions in D:
class D : public B, public C
{
public:
using B::foo;
using C::bar;
int B::bar() { return 0; }
int C::foo() { return 0; }
};
You need to make your base classes virtual in order for them to inherit properly. The general rule is that all non-private member functions and base classes should be virtual UNLESS you know what you're doing and want to disable normal inheritance for that member/base.