This question already has answers here:
What is the practical use of protected inheritance?
(2 answers)
Closed 8 years ago.
I'm trying to experiments with inheritance in c++. I've written the following code:
#include <stdio.h>
class A
{
public:
virtual void foo();
};
class B: A
{
void foo();
};
void B::foo()
{
printf("Derived class");
}
void A::foo()
{
printf("Base class");
}
int main()
{
A *a= new B();
a->foo();
}
But I've an error described as
test.cpp: In function ‘int main()’: test.cpp:26:14: error: ‘A’ is an
inaccessible base of ‘B’
It works fine if I replace the line class B: A to class B: public A. But using this fact I really don't understand in what case private and protected inheritance may be needed. It's useless for me now.
You are accessing B::foo() using A*. But both the inherited A::foo() and overridden B::foo() are private.
About inheritance concept:
public : derived class IS-A base class
private/protected: derived class has a base class \ derived class is implemented-in-terms of base class.
Inherit publicly when derived object is replaceable to base object. Inherit privately when derived class only needs the implementation of base class (not interface). But in the later case Composition is preferred approach than inheritance.
check this and this
Related
This question already has answers here:
If a private virtual function is overridden as a public function in the derived class, what are the problems?
(3 answers)
Overriding public virtual functions with private functions in C++
(7 answers)
Closed 4 years ago.
class A
{
public:
virtual void fun()
{
cout << "A Fun";
}
};
class B:public A
{
private:
void fun()
{
cout << "B Fun";
}
};
class C:public B{};
int main()
{
//Case1
A *ptr = new C();
ptr->fun();
/*
OUTPUT : B Fun
*/
//Case 2
B *ptr2 = new C();
ptr2->fun();
/*
ERROR:
main.cpp: In function ‘int main()’:
error: ‘virtual void B::fun()’ is private within this context
ptr2->fun();
^
note: declared private here
void fun()
^~~
*/
return 0;
}
In case 1 : I am able to call the private fun() in class B , but why I am not able to call the private fun() in case 2?
Why fun() in class B is having two different kind of behaviour?
I mean to say that when I make pointer of type A then fun() of class B act as public function but when I make pointer of type B then fun() of class B act as private function.
In case 1 : I am able to call the private fun() in class B [...]
No, you are not being able to call / are not calling a private method in a class B. You are calling a public method from class A that happens to be overriden in the child class.
This is especially useful when unit testing a private method. You simply make your class inherit from a dummy base class that declares the method of interest as public and (possibly pure) virtual.
Private-ness and public-ness is a purely compile time property of a member of a class/struct. The compiler checks if you have access to a member while compiling the code.
So in your code:
B b;
b.fun(); // Error! B::fun is private in this context!
A& a = static_cast<A&>(b); // `a` is a reference to `b`
a.fun(); // okay, A::fun is public.
// It just so happen that A::fun is virtual,
// So the function dispatched at runtime will be B::fun
// But the compiler has no mean to check this.
The behavior at runtime is determined if the function has been overridden, and only if the function A::fun is virtual. By overridding a virtual function, you must agree that expression using A will be dispatched to B, regardless what restrictions is on B. Code calling A::fun polymorphically must work with any subclasses, because code that deal with the base class cannot know the derived classes.
This question already has answers here:
C++ "virtual" keyword for functions in derived classes. Is it necessary?
(9 answers)
Closed 6 years ago.
The following code is late binding test() method but shouldn't it bind early? because test() method is not virtual in class B(but in class A), and we are using pointer of class B.
class A{
public:
virtual void test(){
cout<<"test a";
}
};
class B : public A{
public:
void test(){
cout<<"Test b";
}
};
class C: public B{
public:
void test(){
cout<<"test c";
}
};
int main(){
B *bp;
C objc;
bp = &objc;
bp->test(); // test c
}
Once a function has been declared virtual in a class, it's always virtual in the classes that inherit from that class, whether you use the virtual keyword or not.
So in your class C, the test() function is actually overriding B and A's own test() functions.
N4296, 10.3§2 (draft version):
If a virtual member function vf is declared in a class Base and in a
class Derived, derived directly or indirectly from Base, a member
function vf with the same name, parameter-type-list (8.3.5),
cv-qualification, and ref-qualifier (or absence of same) as Base::vf
is declared, then Derived::vf is also virtual (whether or not it is so
declared) and it overrides Base::vf.
Emphasis by me.
A virtual function remains virtual in all derived classes, regardless if it is declared as virtual in the derived classes.
This question already has answers here:
Function with same name but different signature in derived class not found
(2 answers)
Closed 5 years ago.
I need to understand why C++ don't allow to access Grandparent overloaded functions in Child if any of the overloaded function is declared in Parent. Consider the following example:
class grandparent{
public:
void foo();
void foo(int);
void test();
};
class parent : public grandparent{
public:
void foo();
};
class child : public parent{
public:
child(){
//foo(1); //not accessible
test(); //accessible
}
};
Here, two functions foo() and foo(int) are overloaded functions in Grandparent. But foo(int) is not accessible since foo() is declared in Parent (doesn't matter if it declared is public or private or protected). However, test() is accessible, which is right as per OOP.
I need to know the reason of this behavior.
The reason is method hiding.
When you declare a method with the same name in a derived class, base class methods with that name are hidden. The full signature doesn't matter (i.e. cv-qualifiers or argument list).
If you explicitly want to allow the call, you can use
using grandparent::foo;
inside parent.
Just imagine that a library has this class:
struct Base {
};
In your code you use that class as a base class:
struct Derived : Base {
void f(int);
};
and now you write:
Derived d;
d.f('a');
And now you get the shiny new version 2.0 of that library, and the base class has changed a bit:
struct Base {
void f(char);
}
If overloading applied here, your code would break.
I believe, a derived class can override only those functions which it inherited from the base class. Is my understanding correct.?
That is if base class has a public member function say, func, then the derived class can override the member function func.
But if the base class has a private member function say, foo, then the derived class cannot override the member function foo.
Am i right?
Edit
I have come up with a code sample after studying the answers given by SO members. I am mentioning the points which i studied as comments in the code. Hope i am right. Thanks
/* Points to ponder:
1. Irrespective of the access specifier, the member functions can be override in base class.
But we cannot directly access the overriden function. It has to be invoked using a public
member function of base class.
2. A base class pointer holding the derived class obj's address can access only those members which
the derived class inherited from the base class. */
#include <iostream>
using namespace std;
class base
{
private:
virtual void do_op()
{
cout << "This is do_op() in base which is pvt\n";
}
public:
void op()
{
do_op();
}
};
class derived: public base
{
public:
void do_op()
{
cout << "This is do_op() in derived class\n";
}
};
int main()
{
base *bptr;
derived d;
bptr = &d;
bptr->op(); /* Invoking the overriden do_op() of derived class through the public
function op() of base class */
//bptr->do_op(); /* Error. bptr trying to access a member function which derived class
did not inherit from base class */
return 0;
}
You can override functions regardless of access specifiers. That's also the heart of the non-virtual interface idiom. The only requirement is of course that they are virtual.
But if the base class has a private member function say, foo, then the derived class cannot override the member function foo.
In Java, you can't. In C++, you can.
You are correct in that to override a function in a derived class, it must inherit it from the base class (in addition, the base class function must be virtual). However you are wrong about your assumption that virtual functions are not inherited. For example, the following works well (and is actually a known idiom for precondition/postcondition checking):
class Base
{
public:
void operate_on(some thing);
private:
virtual void do_operate_on(some thing) = 0;
};
void Base::operate_on(some thing)
{
// check preconditions
do_operate_on(thing);
// check postconditions
}
class Derived: public Base
{
// this overrides Base::do_operate_on
void do_operate_on(some thing);
};
void Derived::do_operate_on(some thing)
{
// do something
}
int main()
{
some thing;
Base* p = new Derived;
// this calls Base::operate_on, which in turn calls the overridden
// Derived::do_operate_on, not Base::do_operate_on (which doesn't have an
// implementation anyway)
p->operate_on(thing);
delete p;
}
A way to see that private methods are really inherited is to look at the error messages generated by the following code:
class Base
{
private:
void private_method_of_B();
};
class Derived:
public Base
{
};
int main()
{
Derived d;
d.private_method_of_B();
d.method_that_does_not_exist();
}
Trying to compile this with g++ leads tot he following error messages:
privatemethodinheritance.cc: In function 'int main()':
privatemethodinheritance.cc:4: error: 'void Base::private_method_of_B()' is private
privatemethodinheritance.cc:15: error: within this context
privatemethodinheritance.cc:16: error: 'class Derived' has no member named 'method_that_does_not_exist'
If class Derived wouldn't inherit that function, the error message would be the same in both cases.
No You can not over ride any function in base class .
My reason for this notion is that if you define the function in derived class that has the same function signiture in base class , the base class function will become hidden for derived class .
For more information about this exciting issue just visit :
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Foverload_member_fn_base_derived.htm
It's also depends on the type of inheritance
class Derived : [public | protected | private] Base { };
In order to override a function inherited from base class, it should be both virtual, and classified as public or protected.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
C++ : implications of making a method virtual
Why is 'virtual' optional for overridden methods in derived classes?
I wonder, what is documented behavior in the following case:
You have
class A
{
virtual void A()
{
cout << "Virtual A"<<endl;
}
void test_A()
{
A();
}
}
class B: public A
{
void A()
{
cout << "Non-virtual A in derived class"<<endl;
}
void test_B()
{
A();
}
}
A a; B b;
a.test_A();
b.test_A();
b.test_B();
What it supposed to do according to C++ standard and why?
GCC works like B::A is also also virtual.
What shoudl happen in general when you override virtual method by non-virtual one in derived class?
The sub-class member function is implicitly virtual if a virtual base-class member function with the same name and signature exists.
The code should not compile as you cannot name a method with the name of the class. But regarding what I understand that is your real question:
Will making a method virtual imply that the same method in all the derived classes is virtual even if the virtual keyword is not present?
The answer is yes. Once a method is declared virtual in a class, then all overrides of that method will be virtual, and the virtual keyword is optional in derived classes (even if I recommend typing it, if only for documentation purposes). Note that for a method in a derived class to be an override it has to have the same name and signature, with only potential difference being a covariant return type:
struct A {};
struct B : A {};
struct base {
virtual A* foo();
virtual A* bar();
};
struct derived : base {
virtual B* foo(); // override, covariant return type
virtual int bar(); // not override, return type is not covariant
virtual A* bar(int); // not override, different argument list
};
This code is ill-formed. A constructor cannot have a return type (as you have done for the constructor of 'A'). Also a constructor cannot be virtual.
After fixing A's constructor, class B is ill-formed as the constructor of A is private.
So, there are many problems with this code (including missing semicolons at the class definitions).
According to standard it should be
A a; B b;
a.test_A(); //"Virtual A"
b.test_A(); //Non-virtual A in derived class
b.test_B(); //Non-virtual A in derived class