I am trying to update the value of a number, to make it 30, by accessing 3 different functions ( they have the same name ) from 3 different classes. Can you please help me ? I have to use the functions in class D. I tried with creating 3 different objects and applying to each of them the function, but it did not work
using namespace std;
int callA=0;
int callB=0;
int callC=0;
class A
{
protected:
void func(int & a)
{
a=a*2;
callA++;
}
};
class B
{
protected:
void func(int & a)
{
a=a*3;
callB++;
}
};
class C
{
protected:
void func(int & a)
{
a=a*5;
callC++;
}
};
class D
{
int val;
public:
//Initially val is 1
D()
{
val=1;
}
//Implement this function
void update_val(int new_val)
{
A a;
B b;
C c;
c.func(b);
b.func(a);
}
};
You can't access from the D class to the func method of A,B,C classes because they are protected.
For accede to protected method of a class your class should be a friend or a derived class.
Otherwise you need to set their visibility to public.
For more read here
Using derived class, this should work;
using namespace std;
int callA=0;
int callB=0;
int callC=0;
class A
{
protected:
void func(int & a)
{
a=a*2;
callA++;
}
};
class B
{
protected:
void func(int & a)
{
a=a*3;
callB++;
}
};
class C
{
protected:
void func(int & a)
{
a=a*5;
callC++;
}
};
class D : public A, public B, public C
{
int val;
public:
//Initially val is 1
D()
{
val=1;
}
//Implement this function
void update_val(int new_val)
{
// if new_val is '1'
//now you can call func methods;
A::func(new_val);
B::func(new_val);
C::func(new_val);
// then if you print new_val it is '30'
// c.func(b); // You can't pass b. b isn't an integer
// b.func(a); // idem
}
};
// ..... //
int main(){
D d;
d.update_val(1);
}
#include<iostream>
using namespace std;
int callA=0;
int callB=0;
int callC=0;
class A
{
public:
void func(int & a)
{
a=a*2;
callA++;
}
};
class B
{
public:
void func(int & a)
{
a=a*3;
callB++;
}
};
class C
{
public:
void func(int & a)
{
a=a*5;
callC++;
}
};
class D
{
public:
int val;
//Initially val is 1
D()
{
val=1;
}
//Implement this function
void update_val()
{
A a;
B b;
C c;
a.func(val);
b.func(val);
c.func(val);
}
};
int main ()
{
D d;
d.update_val();
std::cout<<d.val<<std::endl;
return 0;
}
Related
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
Is it possible to call run() with p without concerning different class they are(for example class cast on a void*) and different implementation of run() in each class?
class A
{
void func()
{
//new B
//new C
//new D
//*p points to the instance of one of B,C,D
p->run(i);
}
// some pointer *p
}
class B
{
void run(int i);
}
class C: public B
{
void run(int i);
}
class D: public B
{
void run(int i);
}
This works:
#include <iostream>
class B
{
public:
virtual int run(int i);
};
class A
{
public:
int func(B* obj, int i)
{
return obj->run(i);
}
};
class C: public B
{
public:
virtual int run(int i){ return 2*i;}
};
class D: public B
{
public:
virtual int run(int i){ return 3*i;}
};
int main(){
A a;
C obj1;
D obj2;
B* ptr1 = &obj1;
B* ptr2 = &obj2;
std::cout << a.func(ptr1, 3) << "\n";
std::cout << a.func(ptr2, 3) << "\n";
}
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.
I have a class A and class B, B here is a subclass of A:
class A {
public:
A(int a) : obj(a) {}
void init() {
if(magic_str == "hello") {
// do init c
c = 7;
}
}
private:
int obj;
int c;
protected:
string magic_str;
};
class B : public A {
public:
B(int a, double _b) : A(a), b(_b){}
void set_magic_str() {
magic_str = "hello";
}
private:
double b;
};
Above, the init function in A must be constructed in A, but must be called after magic_str is initialized. magic_str must be initialized in class B because there are some user-define logic.
How can I force B to invoke init in A?
To sum up, I want to split constructor code in A into two piece, and between these two piece, some user-defined behavior must be initialized in his subclass B.
One way would be to pass the magic string as an constructor to As constructor and call init in the constructor.
class A {
public:
A(int a, string m) : obj(a), magic_str(m)
{
init();
}
void init() {
if(magic_str == "hello") {
// do init c
c = 7;
}
}
private:
int obj;
int c;
protected:
string magic_str;
};
class B : public A {
public:
B(int a, double _b) : A(a,get_magic_str()), b(_b){}
static string get_magic_str() {
return "hello";
}
private:
double b;
};
Another way would be to use the builder pattern and let it handle the complex way you want your object to be created:
class A {
public:
A(int a) : obj(a) {}
void init() {
if(magic_str == "hello") {
// do init c
c = 7;
}
}
private:
int obj;
int c;
protected:
string magic_str;
};
class B : public A {
public:
static B create (int a, double _b) // <-- only allow instances to be created via this function
{
B b = B(a, _b);
b.init();
return b;
}
void set_magic_str() {
magic_str = "hello";
}
private:
B(int a, double _b) : A(a), b(_b){} //maybe protected
double b;
};
As init is a non-private member function of A, B being derived form A, can call init.
Call it after magic_string is set eg. the constructor.
A::init();
Otherwise,change A's constructor , and use this in B.
A(int a, string s)
B(int a, double _b): A (a, magic_str)...
I would change the logic to something like:
class A {
public:
A(int a) : obj(a), c(0) {}
protected:
void set_magic_str(const std::string& s) {
magic_str = s;
if (magic_str == "hello") {
// do init c
c = 7;
}
}
private:
int obj;
int c;
std::string magic_str;
};
class B : public A {
public:
B(int a, double _b) : A(a), b(_b){}
void set_magic_str() {
A::set_magic_str("hello");
}
private:
double b;
};
I like the results of this code but i was curious, is it possible to call B::VFunc() from main()? I know writing B::VFunc(); inside of C will call it but is it possible to call the function from outside of the object?
http://ideone.com/Dg8aa
#include <cstdio>
class I { public: virtual void VFunc()=0; };
class B : public I { public: void VFunc() { printf("B\n"); } };
class C : public B { public: void VFunc() { printf("C\n"); } };
int main(){
C v;
B&i = v;
i.VFunc();
}
output:
C
This will do it:
#include <cstdio>
class I { public: virtual void VFunc()=0; };
class B : public I { public: void VFunc() { printf("B\n"); } };
class C : public B { public: void VFunc() { printf("C\n"); } };
int main(){
C v;
B&i = v;
i.B::VFunc();
}
Example: http://ideone.com/MfyYJ
You can resort to slicing:
C v;
B i = (B)v;
http://ideone.com/YVI2T
The dynamic type of v is lost, so B::VFunc is called.