Accessing Inherited Functions - c++

In multiple inheritance,where all the base class contains same function name with different functionality, we can access the protected function from particular base class using "::" scope resolution operator.
However, I tried something else. I created the objects of the base class in inside the child class. And tried calling the function using through object of that particular class.
But I was getting the following compiler error:
"‘void A::func(int&)’ is protected within this context."
Please let me know where did i go wrong.
#include <iostream>
using namespace std;
class A
{
protected:
void func(int & a)
{
a = a * 2;
}
};
class B
{
protected:
void func(int & a)
{
a = a * 3;
}
};
class C
{
protected:
void func(int & a)
{
a = a * 5;
}
};
class D : public A,public B,public C {
public:
int a;
A a_val;
B b_val;
C c_val;
void update_val(int new_val)
{
a = new_val;
a_val.func(a);
b_val.func(a);
c_val.func(a);
}
void check(int);
};
void D::check(int new_val)
{
update_val(new_val);
cout << "Value = " << a << endl;
};
int main()
{
D d;
int new_val;
cin >> new_val;
d.check(new_val);
}

If you want to keep your code with the base classes as having independent functionality and still remaining protected the easiest way to resolve your issue is by slightly changing the name of your protected functions and adding a public function that calls the protected members: See these class declarations for example:
class A {
public:
void func( int& a ) {
func_impl( a );
}
protected:
void func_impl( int& a ) {
a = a * 2;
}
};
class B {
public:
void func( int& b ) {
func_impl( b );
}
protected:
void func_impl( int& b ) {
b = b * 3;
}
};
class C {
public:
void func( int& c ) {
func_impl( c );
}
protected:
void func_impl( int& c ) {
c = c * 5;
}
};
class D : public A, public B, public C {
public:
int a;
A a_val;
B b_val;
C c_val;
void update_val( int val ) {
a = val;
a_val.func( a );
b_val.func( a );
c_val.func( a );
}
void check( int );
};
void D::check( int val ) {
update_val( val );
std::cout << "Value = " << a << std::endl;
}
This provides a nice public interface to call the protected member functions. This also resolves the issue of accessing the protected members. When I run your program and input a value of 5 it returns a result of 150 and works as expected.
This snippet should show you how inheritance works and when you can and can not access protected members:
class DerivedA : public Base {
public:
Base b;
void call_message() {
b.message(); // Protected Member of Base class can not be accessed
}
};
class DerivedB : public Base {
public:
void call_message() {
message(); // This works without problem!
}
};
Just as I did above one way to resolve this is by adding a public interface caller to the protected implementation.
class Base {
public:
void message() {
message_impl();
}
protected:
void message_impl() {
std::cout << "This is a protected member of Base\n";
}
};
Now you can do this:
class DerivedA {
public:
Base b;
void call_message() {
b.message(); // Accessible through public interface.
}
};

When you are in your derived class, it has access to its own ancestor methods. But it doesn't have access to your variables member protected and private methods and variables.
Redesign your code, you are trying things and contorting the other classes design for bad reasons. Francis' code is a good solution, but D doesn't need to inherit from anything.

If you don't want to create another function, you can do something like this:
#include <iostream>
using namespace std;
class A
{
protected:
void func(int & a)
{
a = a * 2;
}
};
class B
{
protected:
void func(int & a)
{
a = a * 3;
}
};
class C
{
protected:
void func(int & a)
{
a = a * 5;
}
};
class D : public A,public B,public C {
public:
int a;
void update_val(int new_val)
{
a = new_val;
this->A::func(a);
this->B::func(a);
this->C::func(a);
}
void check(int);
};
void D::check(int new_val)
{
update_val(new_val);
cout << "Value = " << a << endl;
};
int main()
{
D d;
int new_val;
cin >> new_val;
d.check(new_val);
}
This works because, this refers to the current instance of class D, and it already inherits class A, class B, class C. So you can directly access the protected functions of the respective classes.
Remember: It will not work if you have not inherited the classes.

Related

How do I call an overridden method that was declared after the class calling it?

Say I have this code:
class A
{
public:
A(){};
void some_func(){
std::cout << 1;
};
};
class B
{
A* my_A;
public:
B(A* a) : my_A{a} {};
void use_A()
{
my_A->some_func();
}
};
class C : public A
{
public:
C(){};
void some_func()
{
std::cout << 2;
}
};
int main()
{
C new_c;
B new_b(&new_c);
new_b.use_A();
}
Now this compiles just fine, however use_A() is calling the original some_func(), not the override declared after. How can I do that? I expect the program to print 2, not 1.
You need to declare A::some_func() as virtual in order for C to override it, eg:
class A
{
public:
A(){};
virtual void some_func(){ // <--
std::cout << 1;
};
};
class B
{
A* my_A;
public:
B(A* a) : my_A{a} {};
void use_A()
{
my_A->some_func();
}
};
class C : public A
{
public:
C(){};
void some_func() override // <--
{
std::cout << 2;
}
};
int main()
{
C new_c;
B new_b(&new_c);
new_b.use_A(); // prints 2, not 1
}
Online Demo

Overriding protected field members in C++ not working?

In the following, I expected class Child's protected field member _AorB to be of type B, and not A, but reality shows otherwise.
What am I mis-understanding, and how can I adjust the code for the desired behavior?
class A{
public:
void doit(){
std::cout<<" this is A!"<<std::endl;
}
};
class B{
public:
void doit(){
std::cout<<" this is B!"<<std::endl;
}
};
class Parent{
public:
void doit(){
_AorB.doit();
}
protected:
A _AorB;
};
class Child: public virtual Parent{
protected:
B _AorB;
};
int main()
{
cout<<"Hello World";
auto c = Child();
c.doit(); // I expected this to print "This is B" because c is Child(), and Child class's _AorB is of type B.
return 0;
}
You can make such changes:
template <typename AorB>
class Parent{
public:
void doit(){
_AorB.doit();
}
protected:
AorB _AorB;
};
class Child: public virtual Parent<B> {
}
Also take a look at What are the rules about using an underscore in a C++ identifier?
Reserved in any scope, including for use as implementation macros:
identifiers beginning with an underscore followed immediately by an uppercase letter
273K's answer is excellent.
Depending on what kind of problem you are trying to solve and how the data is held in the hierarchy, you could use a std::variant<A, B> to allow "flippy" behavior based on the type, and access that member variable through a virtual getter member function.
#include <iostream>
#include <variant>
class A {
public:
void doit() {
std::cout << " this is A!\n";
}
};
class B {
public:
void doit() {
std::cout << " this is B!\n";
}
};
class Parent {
public:
virtual ~Parent() = default;
void doit() {
auto ab = get_AorB();
std::visit([](auto arg) { arg.doit(); }, ab);
}
virtual auto get_AorB() -> std::variant<A, B> {
return _a;
}
protected:
A _a;
};
class Child : public virtual Parent {
protected:
B _b;
auto get_AorB() -> std::variant<A, B> override {
return _b;
}
};
int main() {
std::cout << "Hello World";
auto c = Child();
c.doit(); // "this is B!"
}

List of multiple class to run same function name C++ [duplicate]

This question already has answers here:
How to store object of different class types into one container in modern c++?
(2 answers)
Closed 3 years ago.
I have multiple classes with same function as below
class A
{
void display()
{
// display something
}
};
class B
{
void display()
{
// display something two
}
};
I want to store difference class at a list or a vector and loop to call the same function with same name
int main()
{
A * a;
B * b;
//list or vector to store object
std::vector < Something that can store different class > listofclass;
listofclass.emplace_back(a);
listofclass.emplace_back(b);
for (int i = 0; i < listofclass.size(); i++)
{
listofclass[i].display();
}
}
Is that possible to do like this?
Because there is separate classes, having different purpose, and now i try to group them together
Or there is other alternative way to achieve something like this
If you control the definition of A and B, you can write a common base class, and have them inherit it.
class can_display {
public:
virtual void display() = 0;
virtual ~can_display() = default;
};
class A : public can_display
{
void display() override
{
// display something
}
};
class B : public can_display
{
void display() override
{
// display something two
}
};
int main()
{
A a;
B b;
std::vector<can_display *> displayables;
displayables.push_back(&a);
displayables.push_back(&b);
for (can_display * displayable : displayables)
{
displayable->display();
}
}
As an alternative to changing the definition of A and B to inherit from a common base, you can have a wrapper that inherits.
template <typename T>
class can_display_impl {
T * wrapped;
public:
can_display_impl(T * wrapped) : wrapped(wrapped) {}
void display() override { wrapped->display(); }
}
template <typename T>
std::unique_ptr<can_display> make_can_display(T & wrapped) {
return std::make_unique<can_display_impl<T>>(&wrapped);
}
int main()
{
A a;
B b;
std::vector<std::unique_ptr<can_display>> displayables;
displayables.emplace_back(make_can_display(a));
displayables.emplace_back(make_can_display(b));
for (auto & displayable : displayables)
{
displayable->display();
}
}
You have two solutions for this problem:
Use inheritance and just make a abstract class that will be a interface for your classes. In class A and class B just inherit from that interface and in std::vector hold pointer to base class.
#include <vector>
#include <iostream>
#include <memory>
class Interface_display {
public:
virtual void display() = 0;
virtual ~Interface_display(){};
};
class A : public Interface_display
{
public:
void display() override
{
std::cout << "Display from A\n";
}
~A() override = default;
};
class B : public Interface_display
{
public:
void display() override
{
std::cout << "Display from B\n";
}
~B() override = default;
};
int main(void)
{
std::vector<std::unique_ptr<Interface_display>> v;
v.emplace_back(std::make_unique<A>());
v.emplace_back(std::make_unique<B>());
for (const auto &element: v) {
element->display();
}
}
And if you are using c++17, you could use std::variant and wrap objects of your class to std::variant:
#include <vector>
#include <iostream>
#include <variant>
class A
{
public:
void display()
{
std::cout << "Display from A\n";
}
};
class B
{
public:
void display()
{
std::cout << "Display from B\n";
}
};
int main(void)
{
using variant_t = std::variant<A, B>;
std::vector<variant_t> v;
v.emplace_back(A());
v.emplace_back(B());
for (auto &element: v) {
std::visit([](auto &x) { x.display(); }, element);
}
}
https://wandbox.org/permlink/8VBmziWzafbPZk99
A way to solve this problem is by using polymorphism. You make a superclass, which contains a pure virtual version of this function and let both A and B inherit from this class. By doing this, you can dynamic_cast any pointer of type A or B to a superclass type, on which you have defined the display function.
This will get you something like this
class C {
public:
virtual void display() = 0;
virtual ~C() = default;
};
class A : public C {
public:
void display() override {
std::cout << "A" << std::endl;
};
~A() override = default;
};
class B : public C {
public:
void display(){
std::cout << "B" << std::endl;
};
~B() override = default;
};
So you can do:
C* c = new A();
// You can put the types of C* in the same list, and iterate over this list and do on each element
c->display();
delete c;

How to change the behaviour of a method at runtime?

Short Version:
The main point is that the (complex) state of an instance can be changed by functions that are outside the definition of the class, as such the class can be extended to have all sorts of internal states without polluting the class defintion with many state-setters.
Assume the following code:
class bar
{
virtual void ChangeState()=0;
}
class foo:bar
{
private:
int b;
public:
void ChangeState() {b=3;}
}
What I would like to do is create different functions, then pass them to the function, at runtime, something like
foo.ChangeState(); //b is 3 now
void foo::(?)ChangeState2(){ b=2; };
foo.ChangeState=ChangeState2;
foo.ChangeState(); //b is 2 now
Can such a construct be implemented in C++, without the use of hacks?
Maybe, this will help:
#include <iostream>
namespace so
{
class B
{
friend void change_1( B * );
friend void change_2( B * );
friend void change_3( B * );
int i;
public:
B() : i{ 0 } {}
void change_state( void (*_function)( B * ) )
{
_function( this );
std::cout << i << std::endl;
}
};
void change_1( B * _object )
{
_object->i = -1;
}
void change_2( B * _object )
{
_object->i = -2;
}
void change_3( B * _object )
{
_object->i = -3;
}
} //namespace so
int main()
{
so::B b{ };
b.change_state( so::change_1 );
b.change_state( so::change_2 );
b.change_state( so::change_3 );
return( 0 );
}
Short answer: That's not possible.
What you can do is define multiple classes and choose between them based on some runtime condition. And of course, that object doesn't have to be the full class, we could do something like this:
class foo: public bar
{
private:
class ChangeState
{
public:
virtual void DoChangeState(foo *f) = 0;
};
class ChangeState2
{
public:
virtual void DoChangeState(foo *f) { f->b = 2 } ;
};
class ChangeState3 : public ChangeState
{
public:
virtual void DoChangeState(foo *f) { f->b = 3 } ;
};
ChangeState *stateChanger
public:
foo() { stateChanger = new ChangeState3; }
void SetStateChange2() { delete stateChanger; stateChanger = new ChangeState2; }
~foo() { delete stateChanger; }
void ChangeState() { stateChanger->DoChangeState(this); }
};
I'm sure there are other variations on this theme (and you probably should use a smart pointer).
You can't change the behaviour at runtime using the syntax you describe. You can however if you wish get something similar by using function pointers.
But if I understand what you are trying to accomplish correctly, I would look at implementing the strategy pattern

C++ virtual functions base return type suggestions

I need a base class that gives me primitive type of data's pointer. I add a function in it. I derived types of class. I used void * to support all primitive types as a return type but it is like old C days. It is not good for OOP. Does one have an suggestion to do in a proper way in OOP?
#include <iostream>
class base {
public:
virtual void *getPtr() = 0;
virtual ~base() {};
};
class derivedAType : public base {
protected:
int _i;
public:
derivedAType(int i): _i(0) { _i = i; };
virtual ~derivedAType() {}
virtual void *getPtr() {
return static_cast<void *>(&_i);
}
};
class derivedBType : public base {
protected:
short _s;
public:
derivedBType(short s): _s(0) { _s = s; };
virtual ~derivedBType() {}
virtual void *getPtr() {
return static_cast<void *>(&_s);
}
};
int main()
{
base *b1 = new derivedAType(1203912);
base *b2 = new derivedBType(25273);
std::cout << "b1 : " << *(static_cast<int *>(b1->getPtr()))
<< "\nb2 : " << *(static_cast<short *>(b2->getPtr()))
<< std::endl;
delete b2;
delete b1;
return 0;
}
Make the base class a template class with the data type as the template variable
template<typename DataType>
class base {
virtual DataType* getPtr() = 0;
//...
};
and
class derivedAType : public base<int>
But this changes base class to a template class which means you cant store them together, base<int> is different from base<short>
If this isnt acceptable, the other options is just a tad bit cleaner than your code but abt the same, refer to this question. Basically derived class return types can reflect their true type and i think it should get automatically converted to void*, so you dont have to manually cast the pointer.
Not sure about your problem. But maybe a double callback can help:
class Callback {
public:
virtual void do_int( int i ) const = 0;
virtual void do_short( short s ) const = 0;
/* ... */
}
class base {
public:
virtual void do_stuff(const Callback & c); /* will need a more telling name */
virtual ~base() {};
};
class derivedAType : public base {
protected:
int _i;
public:
derivedAType(int i): _i(0) { _i = i; };
virtual ~derivedAType() {}
virtual void do_stuff(const Callback & c) {
c.do_int( _i );
}
};
class derivedBType : public base {
protected:
short _s;
public:
derivedBType(short s): _s(0) { _s = s; };
virtual ~derivedBType() {}
virtual void do_stuff( const Callback & c) {
c.do_short( _s );
}
};
class print_callback : public Callback {
public:
virtual void do_int( int i ) const { std::cout << i; }
virtual void do_short( short s ) const { std::cout << s; }
}
int main() {
base *b1 = new derivedAType(1203912);
base *b2 = new derivedBType(25273);
std::cout << "b1 : ";
b1->do_stuff(print_callback());
std::cout << "\nb2 : ";
b2->do_stuff(print_callback());
std::cout << std::endl;
delete b2;
delete b1;
return 0;
}
Of course you can simplify this by just storing the created print callback, and using it twice.