This question already has answers here:
Why does an overridden function in the derived class hide other overloads of the base class?
(4 answers)
Closed 1 year ago.
This does not compile:
struct Base
{
void something( int a ) { }
};
struct Derived : public Base
{
static void something()
{
std::unique_ptr<Derived> pointer = std::make_unique<Derived>();
pointer->something( 11 );
}
};
It’s possible to fix with using Base::something but still, is it possible to make inheritance work as advertised even inside methods?
By using the same name for the function in the derived class you hide the symbol from the base class.
You can solve it by pulling in the name from the base class with the using statement:
struct Derived : public Base
{
// Also use the symbol something from the Base class
using Base::something;
static void something()
{
std::unique_ptr<Derived> pointer = std::make_unique<Derived>();
pointer->something( 11 );
}
};
I'm not exactly sure what you are trying to accomplish. I added virtual, and changed the name of the Derived something class function, and put in two variants. One variant calls through virtual inheritance, the other calls Base class member function directly.
#include <iostream>
using std::cout;
namespace {
struct Base {
virtual ~Base();
virtual void something(int a) { std::cout << "Base a:" << a << "\n"; }
};
Base::~Base() = default;
struct Derived : Base {
void something(int b) override { std::cout << "Derived b:" << b << "\n"; }
static void action() {
std::unique_ptr<Derived> pointer = std::make_unique<Derived>();
pointer->something(11);
}
static void other_action() {
std::unique_ptr<Derived> pointer = std::make_unique<Derived>();
pointer->Base::something(11);
}
};
} // anon
int main() {
Derived::action();
Derived::other_action();
}
Related
This question already has answers here:
Changing Function Access Mode in Derived Class
(4 answers)
Closed 3 years ago.
I've been playing around with inheritance and I've tried this code:
#include <iostream>
#include <string>
class Foo
{
public:
virtual void func() = 0;
protected:
virtual void doSum() const = 0;
};
class Bar : public Foo
{
public:
void func() {
doSum();
}
protected:
void doSum() const
{
std::cout << "hi, i'm doing something" << std::endl;
}
};
int main()
{
Foo* ptr = new Bar();
ptr->func();
return 0;
}
So I've also tried replacing the protected keyword in the class Bar with private like this :
private:
void doSum() const
{
std::cout << "hi, i'm doing something" << std::endl;
}
and the code happened to work just the same...
So my question is, is there any difference if I declare a protected method private when implementing a derived class? If so, what are they? Am I even allowed to do this?
So my question is, is there any difference if I declare a protected method private when implementing a derived class?
Yes.
If so, what are they?
That will prevent the next level of derived class from being able to call the derived class's implementation.
class Foo
{
protected:
virtual void doSum() const = 0;
};
class Bar : public Foo
{
private:
void doSum() const
{
std::cout << "hi, i'm doing something" << std::endl;
}
};
class Baz : public Bar
{
public:
void doSum() const
{
//===========================
Bar::doSum(); // NOT ALLOWED
//===========================
}
};
Am I even allowed to do this?
Yes.
So my question is, is there any difference if I declare a protected method private when implementing a derived class?
No. There is no difference. Unfortunately, C++ standard does not impose any requirement on the derived class to place the overriding virtual function within any particular accessibility scope. This means, the base class could declare a virtual method protected, and the derived class could implement the method in public/protected/private scope and the code will still be legal and will work.
class Base {
public:
virtual void f() {}
};
class Derived : private Base {
public:
void f() override {}
};
My question is there any use to such override? Private inheritance implies that you can not store Derived in Base pointer and thus it will never be needed to dynamically dispatch f to the correct type.
Just one example: A function of Derived::f1() can call a (public or protected) functions of Base::f2(), which in turn can call f(). In this case, dynamic dispatch is needed.
Here is an example code:
#include "iostream"
using namespace std;
class Base {
public:
virtual void f() {
cout << "Base::f() called.\n";
}
void f2() {
f(); // Here, a dynamic dispatch is done!
}
};
class Derived:private Base {
public:
void f() override {
cout << "Derived::f() called.\n";
}
void f1() {
Base::f2();
}
};
int main() {
Derived D;
D.f1();
Base B;
B.f2();
}
Output:
Derived::f() called
Base::f() called
Let's consider the following code:
#include <iostream>
class Base
{
public:
void foo() //Here we have some method called foo.
{
std::cout << "Base::foo()\n";
}
};
class Derived : public Base
{
public:
void foo() //Here we override the Base::foo() with Derived::foo()
{
std::cout << "Derived::foo()\n";
}
};
int main()
{
Base *base1 = new Base;
Derived *der1 = new Derived;
base1->foo(); //Prints "Base::foo()"
der1->foo(); //Prints "Derived::foo()"
}
If I have the above stated classes, I can call the foo method from any of Base or Derived classes instances, depending on what ::foo() I need. But there is some kind of problem: what if I need the Derived class instance, but I do need to call the Base::foo() method from this instance?
The solve of this problem may be next:
I paste the next method to the class Derived
public:
void fooBase()
{
Base::foo();
}
and call Derived::fooBase() when I need Base::foo() method from Derived class instance.
The question is can I do this using using directive with something like this:
using Base::foo=fooBase; //I know this would not compile.
?
der1->Base::foo(); //Prints "Base::foo()"
You can call base class method using scope resolution to specify the function version and resolve the ambiguity which is useful when you don't want to use the default resolution.
Similar (Not exactly same case) example is mentioned # cppreference
struct B { virtual void foo(); };
struct D : B { void foo() override; };
int main()
{
D x;
B& b = x;
b.foo(); // calls D::foo (virtual dispatch)
b.B::foo(); // calls B::foo (static dispatch)
}
This question already has answers here:
accessing a protected member of a base class in another subclass
(8 answers)
Closed 7 years ago.
I always thought that I understood inheritance, but obviously I don't. I would like to call a protected member function of another instance of the same parent class from a child class like in the following example code:
#include <iostream>
class Parent {
protected:
void doStuff(){
std::cout << 5 << std::endl;
}
};
class Child : public Parent {
public:
void pubfunc(Parent* p){
p->doStuff();
}
};
int main(){
Child* c = new Child();
Parent* p = new Parent();
c->pubfunc(p);
return 0;
}
However, compilation of this code fails with:
In member function ‘void Child::pubfunc(Parent*)’:
error: ‘void Parent::doStuff()’ is protected
error: within this context
I wouldn't want to make the Child class a friend of the Parent class to avoid forward declarations and forward includes of child classes as much as possible. Also, I don't want to make doStuff public, because it can really mess up the internal structure of Parent when used in the wrong circumstances.
Why does this error happen, and what is the most elegant way to solve it?
Mostly the problem is that if C++ allowed you to access the non-public members of the referent of a base class pointer directly, then you could gain easy access to the data of an object simply by deriving from a common base.
Still this is a known loophole in the C++ type system, as shown below, where you can gain that access without modifying the base class, and without using casts or anything like that.
On the third and gripping hand, what you should do is to support the intended usage directly in the base class, by adding a static member function there, as follows:
#include <iostream>
using namespace std;
class Base
{
protected:
void doStuff()
{
cout << 5 << endl;
}
static void doStuff( Base* p ) { p->doStuff(); }
};
class Derived : public Base
{
public:
void pubfunc( Base* p )
{
doStuff( p );
}
};
auto main() -> int
{
Derived d;
Base b;
d.pubfunc( &b );
}
In my humble opinion this is most clear and elegant.
But for completeness, the type system loophole:
#include <iostream>
using namespace std;
class Base
{
protected:
void doStuff()
{
cout << 5 << endl;
}
};
class Derived : public Base
{
public:
void pubfunc( Base* p )
{
(p->*&Derived::doStuff)();
}
};
auto main() -> int
{
Derived d;
Base b;
d.pubfunc( &b );
}
I recommend the static member function, though.
Protected members are accessible in the class that defines them and in classes that inherit from that class. Sometimes it causes people to be confused when they see this kind of errors. But in fact you call doStuff function for Parent object, it doesn't meter if function call done inside inherited class. The result will be the same if you call doStuff function from main().
class Parent
{
protected:
virtual void doStuff()
{
std::cout << 5 << std::endl;
}
};
class Child : public Parent
{
protected:
void doStuff() override
{
std::cout << 8 << std::endl;
}
public:
void pubfunc(Parent* p)
{
((Child*)p)->doStuff();
}
};
int main()
{
Child* c = new Child();
Parent* p = new Parent();
c->pubfunc(p); // will print 5
c->pubfunc(c); // will print 8
return 0;
}
Consider this code
class Base
{
public:
virtual void print ()
{
std::cout << "Base::print" << std::endl;
}
};
class BaseA : public Base
{
public:
virtual void print ()
{
std::cout << "BaseA::print" << std::endl;
}
};
class Derived : public Base
{
public:
virtual void print ()
{
Base::print (); // <= this will always call Base::print even if I derive from BaseA
std::cout << "Derived::print" << std::endl;
}
};
int main ()
{
Base* a = new Derived;
a->print ();
delete a;
}
From Derived::print I call Base::print which is fine untill I deside to derive my Derived from BaseA instead, whereupon I want of course to call BaseA::print. Changing Base::print to BaseA::print in this particular example is not a problem, but what if I have 20 such virtual functions?
How to ask compiler to call immediate parent's version of the print whatever that is?
Use a typedef:
class Derived: public BaseA {
typedef BaseA Base;
...
Compile-time introspection of a class's immediate bases is not currently possible, although there are proposals (e.g. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3326.pdf).
You could try with templates:
template <class base>
class test: public base
{
virtual void testmethod()
{
base::testmethod();
}
};
Then you could add a typedef:
typedef test<myBaseClass> myDerivedClass;