How to access derived data from base class C++ - c++

class B :I'm in this type of scenario in my project, where I'm in x()function of base class A and need to access the data y from derived class C.
I have declared the object of derived class C and using obj_c i got to the x() function
class A
{
private :
public :
//.....
void x()
{
cout << y ;
}
//.....
};
class B : public A
{
public :
//.....
protected :
//.....
private :
//.....
};
class C : public B
{
public :
//.....
protected :
int y = 10 ;
private :
//.....
};
int main()
{
C obj_c ;
obj_c.x();
}

Place the declaration of y inside the base class. After all, the way you've written your code, A needs to contain a y in order to function.
The derived class can then assign the value by passing it up to A at construction.
class A {
public:
void x() { cout << y; };
protected:
A(int value) : y(value) {}
int y;
}
class B : public A
{
protected:
B(int value) : A(value) {}
}
class C : public B
{
public:
C() : B(10) {}
}

As C inherits from B and B inherits from A, then make function virtual in class. implement it in C and call it directly.

The idea of a base class is that A might be used even if C didn't exist. So where is A going to get y?
What you do in those cases is the Template Method design pattern:
A assumes that inheriting classes will provide a y by requiring that they implement a get_y() method:
#include <iostream>
class A
{
private :
protected:
virtual int get_y() = 0;
public :
//.....
void x()
{
std::cout << get_y() << std::endl;
}
//.....
};
class B : public A
{
public :
//.....
protected :
//.....
private :
//.....
};
class C : public B
{
public :
//.....
protected :
int get_y()
{
return 10;
}
private :
//.....
};
int main()
{
C obj_c ;
obj_c.x();
}

Related

c++ [diamond configuration] How to initialize with inheritance?

I apologize if my question is dumb but i'm a beginner in c++. I'm working on diamond inheritance and i would like to know if it is possible to choose the specific parent class which will initilize an attribute for the child class.
To sum up, i would like this code to output B
Thank you for your answers !
PS: i'm working with c++98
#include <iostream>
class A
{
protected:
char m_char;
public:
A(): m_char('A'){};
char getChar(){return m_char;};
~A(){};
};
class B : virtual public A
{
private:
public:
B() {m_char = 'B';};
~B(){};
};
class C : virtual public A
{
private:
public:
C() {m_char = 'C';};
~C(){};
};
class D : public B, public C
{
private:
public:
D() {m_char = B::m_char;};
~D(){};
};
int main(void)
{
D d;
std::cout << d.getChar() << std::endl;
}
Virtual base classes are initialized In depth-first, left-to-right order. So you would need to name B second in your inheritance for D to call its constructor last and thus setting the variable to B at the end.
class D : public C, public B
m_char = B::m_char; is self assignment (there is only one m_char).
In virtual inheritance, it is the most derived class which initialize the virtual class (body does assignment).
How about being explicit in construction:
#include <iostream>
class A
{
protected:
char m_char;
public:
A() : m_char('A') {}
char getChar() const { return m_char; }
virtual ~A() {}
};
class B : virtual public A
{
public:
B() : A('B') {}
};
class C : virtual public A
{
public:
C() : A('C') {}
};
class D : public B, public C
{
public:
D() : A('B'), B(), C() {}
};
int main()
{
D d;
std::cout << d.getChar() << std::endl;
}

Apply "Has a" method and remove inheritance

class A {
class B {
public:
void doSomething();
};
class C : public B {};
class D : public B {};
};
// In B.hpp file
class hello {
class hi {};
class world : public hi, public C {};
};
// In main.cpp file
int main() {
world my_world;
my_world.doSomething();
}
In this code, I want to remove the inheritance between class B and class C. When I instantiate class world, I should still be able to access doSomthing() method from class world.
Is there a way to implement "Has a" method which is as per my understanding a pointer to the base class?
As I mentioned in a comment, the code proposed in the question is incorrect as written. Class members default to being private, so you need to explicitly mark them as public if you want to be able to access them from outside of that class's context. Furthermore, you are missing some scope resolution operators and at least one semicolon. This is the corrected version of your current code. I've also added some code so that the doSomething function has an observable effect—i.e., so that it actually does something.
class A
{
public:
class B
{
public:
void doSomething() { std::cout << "Hello, world!\n"; };
};
class C : public B
{ };
class D : public B
{ };
};
class hello
{
public:
class hi
{ };
class world : public hi, public A::C
{ };
};
int main()
{
hello::world my_world;
my_world.doSomething();
}
Inheritance means "is-a", whereas composition means "has-a". What you have now (as shown above) is inheritance, so you're modeling "is-a". If you want "has-a" instead, So, you want composition. Simply change C to have a member of type B:
class A
{
public:
class B
{
public:
void doSomething() { std::cout << "Hello, world!\n"; };
};
class C
{
public:
B b;
};
class D : public B
{ };
};
class hello
{
public:
class hi
{ };
class world : public hi, public A::C
{ };
};
int main()
{
hello::world my_world;
my_world.b.doSomething();
}
Now, in this code, C has a B. It is named b (but you could name it whatever you wanted).
If you don't want to require that doSomething be accessed from the b member, then you'll need to write a wrapper function. That would even allow you to keep the b member private.
#include <iostream>
class A
{
public:
class B
{
public:
void doSomething() { std::cout << "Hello, world!\n"; };
};
class C
{
B b;
public:
void doSomething() { b.doSomething(); }
};
class D : public B
{ };
};
class hello
{
public:
class hi
{ };
class world : public hi, public A::C
{ };
};
int main()
{
hello::world my_world;
my_world.doSomething();
}

C++ Class in class method inheritance

I have the following structure, and I would like to call foo from D. How is it possible? I got the error message, that I commented at the line below.
class A
{
protected:
class B
{
public:
B(x)
{
//...
}
protected:
virtual void foo()
{
//...
}
};
};
class C : public A
{
protected:
class D : public A::B
{
public:
D(x) : B(x)
{
//empty
}
};
void bar()
{
D var = D(x);
var.foo(); //cant access protected member in class A::B
}
};
foo() is protected member function of B, means that foo() is only allowed to be called from its subclass( child class).
bar() is member function of C, and C is inheritance from A. So ,C is not subclass of B.
If you put bar in D, that's OK.As code below:
class A
{
protected:
class B
{
public:
B(int x)
{
//...
}
protected:
virtual void foo()
{
//...
}
};
};
class C : public A
{
protected:
class D : public A::B
{
public:
D(int x) : B(x)
{
//empty
}
// Here is OK, while D is subclass of B
void bar()
{
int x;
D var = D(x);
var.foo(); //cant access protected member in class A::B
}
};
// void bar()
// {
// int x;
// D var = D(x);
// var.foo(); //cant access protected member in class A::B
// }
};
int main(){
return 0;
}
Try a friend class. You can make D a friend of B, and that should allow D to call foo().
Actually you are trying to access from the class C a protected method of the class D ==> You can't access protected methods from the external of a class.
One solution could be to declare C as a friend class of D so C can access protected methods:
// ...
class D : public A::B
{
public:
D(x) : B(x)
{
//empty
}
// Declare C as friend of D
friend class C;
};
// ...
Adding the friendship declaration your code will compile and will work as expected.
You might want foo() to be public in D even though it is protected in A::B
If so you can add the following line after the public: line in the definition of D
using A::B::foo;
Thanks for the answer. Making the foo function public is really a solution, but I really want foo only available from inherited class. The friend modifier is a thing, what many people hate, because it gives you access for things, thats you should not access.
But also you were right guys, I should access B::foo from D (from constructor is not an option is my case). I could create a function, which calls the original foo, so my solution is:
class A
{
protected:
class B
{
public:
B(x)
{
//...
}
protected:
virtual void foo()
{
//...
}
};
};
class C : public A
{
protected:
class D : public A::B
{
public:
D(x) : B(x)
{
//empty
}
Dfoo()
{
B::foo();
}
};
void bar()
{
D var = D(x);
var.Dfoo();
}
};
The solution was easy, but I did not know that a function (what is not static) can be called like this :)

method of a pointer pointing to an object is inaccesible

my class looks like this
class A{
private:
int id;
public:
A();
int getId();
}
class B{
private:
public:
B();
}
Implementation
//constructor
B::B() : A(){
}
B extends A class.
Okay in my main cpp I have a function like this
bool checkID(B *obj){
if(obj->getId() > 1){ return true; } else { return false; }
}
However, the obj->getId() , getId() says its inaccesible.
Why is it?
By default C++ uses private inheritance. Use B : public A to publicly inherit from A. Also you need to define the inheritance in the declaration.
class B : public A {
public:
B();
}
B must derive from A to have A's members be accessible from B objects.
class B : public A { ... };

Is not a nonstatic data member or base class of

I have the following classes, and I'm trying to access a base member using an object of class H, and I get an H::a is ambiguous warning.
class E {
public:
E() : a(11) { }
int a;
};
class F : public E {
public:
F() : b(22) { }
int b;
};
class G : public E {
public:
G() : c(33) { }
int c;
};
class H: public F, public G {
public:
H() : d(44) { }
int d;
};
I tried making the data member a static, but then it doesn't let me initialize it in the base constructor. What's a solution to these two problems?
Class "H" has two variables called "a", one derived from F and one from G. You can either use a qualifier,
H::a
or you can use the "virtual" inheritance specifier (see https://stackoverflow.com/a/419999/257645)
#include <iostream>
struct A {
int a;
};
struct B : virtual public A {
};
struct C : virtual public A {
};
struct D : virtual public B, virtual public C {
void d1() { a = 1; }
void d2() { a = 2; }
};
int main() {
D d;
d.d1();
d.d2();
std::cout << d.a << std::endl;
}
http://ideone.com/p3LPe0