I have a derived class (class B) from a base class (class A). Class A has a protected virtual function foo() which I want to override and use it as private in derived class.
Class A{
protected:
virtual void foo() = 0;
}
I am wondering whether the following
Class B: public Class A
private:
virtual void foo();
and
Class B: private Class A
private:
virtual void foo();
are the same.
They are not the same. In the first example, B is-an-A, in the second it isn't. So in the first case you can have code such as
void foo(const A& a);
which accepts A and B as arguments. With private inheritance, you could not do that. For example,
A a;
B b;
foo(a); // OK with private and public inheritance
foo(b); // OK only with public inheritance, i.e. B is an A.
No, your two cases are not the same.
In the second case class B can't be casted to class A, because a private base class is hidden. in this aspect would get the same behavior as if class A would be a member of class B.
No both are not same
In public inheritance class A's foo() will be protected member in class B
In private inheritance class B can only access the public members of the class A so there will not present any foo() of class A in class B.
Related
I am new to OO programming and I was wondering how to solve the following question -
I have the following:
class A
{
public:
A() {};
~A() {};
virtual functionA() = 0;
}
class B: public A
{
public:
B() {};
~B() {};
functionA();
functionB();
}
Is there a way to access functionB using an object of the base class A? If no, why is it not possible? If yes, how does one do it? I tried to find this answer on this site but I didn't find anything concrete.
I would modify your example slightly to give you a better understanding:
class Animal
{
public:
A() {};
~A() {};
virtual Eat() = 0;
}
class Bird: public Animal
{
public:
B() {};
~B() {};
Eat();
Fly();
}
Should an Animal object be allowed to access the function Fly which belongs to Bird ?
No, because not all Animals are Birds.
But if you are sure than a specific Animal object is a Bird, then you can downcast the Animal object to Bird and then call Fly function.
However, this is not generally recommended. Upcasts (casting Bird to Animal) are okay because all Birds are Animals.
In general this is not possible. Class A can't access derived methods in Class B. The general relationship is upward for inheritance. Imagine a Class C that also has functionB, the resolution would be ambiguous.
class A
{
}
class B:public A
{
void functionB() {};
}
class C:public A
{
void functionB() {}
}
main()
{
A a;
a.functionB(); // What to call here?
}
With that being said, if an instance is in fact a B then a downcast could be used.
main()
{
B b;
A&a = b; // ok since a B is-a A
auto & b1 = dynamic_cast<B&>(a); // ok since this particular instance is-a B
b1.functionB();
}
perhaps this is what you were reaching for.
You can access only virtual method of B using the object A. This is called runtime-polymorphism and it is achieved with virtual function. Hence in order to implement the runtime behaviour C++ compiler inserts Virtual Table for every class having virtual function or class inherited from the class that has virtual function.
As in your code, i will make small modification:-
class A
{
public:
A() {};
~A() {};
virtual void functionA() = 0;
virtual void functionC();
}
class B: public A
{
public:
B() {};
~B() {};
void functionA() override; // C++ 11 : override keyword ensures that the function is virtual and is overriding a virtual function from a base class.
void functionB();
}
As the class A contains a virtual function C++ compiler inserts a pointer v_ptr called as virtual table pointer. Compiler also creates a table for that class called as virtual table known as vtable for the class. The table is created compile time v_ptr holds the address of v_table of the corresponding class. vtable is a array of function pointers pointing to virtual function. As functionA is pure virtual so in vtable the address entry for functionA will be null and but functionC has a valid address entry in vtable as it is not pure virtual function.
virtual table contains pointers to functionA() and functionC function of A class. But the implementation is incomplete as functionA is pure virtual. So you can't create object of class A.
As B Class inherits from A class, and as we know A class has a data member v_ptr. B class inherits v_ptr of A class but new virtual table will be created compile time for B class. Hence v_ptr of B class holds the address of vtable of B class. As B class has implemented functionA function. vtable of B class contains pointer to functionA function of B class but pointer to functionC function of base class i.e A class.
A *a = new B();
a->functionA(); //calls B functionA
a->functionC(); //calls A functionC since we haven't overriden this function in B
When a class is derived from a base class, will the member functions of the base class become member function of the derived class. That is, for example if I write:
class A
{
public : void f();
};
class B : public A
{
public : void f1();
};
Now if the question is to name the member functions in class B, then will f() also become a member function of class B ?
then will f() also become a member function of class B ?
No. f() is still a member function of class A, class B just inherits it. In your case it's a public member function and public inherit, means you can call f() on a B object.
B b;
b.f();
On the other hand, class B can define own member function f():
class A
{
public : void f();
};
class B : public A
{
public : void f(); // will hide A::f()
};
Yes, class B has two functions: f1() and f().
If f() was protected in A, too, but f() could only be used from within the member functions of A and B (and from friends).
And if f() was private, B would have only one function f1().
class A {
public : void f();
};
class B : public A
{
public : void f1();
};
Now code is valid.
It is visible. Even when you change f1 name to f it is still visible in B class. If you wanna use it use scope operator ::.
Like this:
A::f()
More about basic inheritence
http://www.learncpp.com/cpp-tutorial/112-basic-inheritance-in-c/
I have class A and B.
class A{
public:
foo();
};
class B : public A{
public:
int x;
};
Assume that there is an object from B class in a test file.How should I call foo function?
object.foo(); // or
object.A::foo();
Other questions:
When do we call a function like that?What if I do multiple inheritance?
Simply object.foo(), and there's not much more to add:
B object;
object.foo();
class B inherits public members of class A, so function foo() also belongs to class B and can be called using B class's object.
B b;
b.foo();
You need to know inheritance in c++. Its just same as
b.x;
See x and foo() both are member of object b even b is object of Class B and its possible because Class B inheritance features from Class A, In your code function foo().
Note Class A has only one member function foo()
A a;
a.foo();
Is valid, But
a.x;
Is not valid
EDIT: Multi-level inheritance Class C inherits Class B and Class B inherits Class A, then
class C : public B{
public:
int y;
};
C c;
c.foo(); // correct
Is also valid.
And
c.x;
c.y;
Also valid, x, y, foo() all are member of Class C.
Notice: What I told you is multi-level Multiple inheritance in C++ is different. Also three access specifiers in C++ are very important in case of inheritance: public private protected in c++
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.
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.