change value of data member of one class from another class - c++

#include <iostream>
using namespace std;
class B{
public:
int x;
void setx(int a){
x =a;
cout<<"Inside set "<<x<<endl;
}
void show();
};
void B::show(){
cout<<"inside show "<<x<<endl;
}
class A{
public:
void func();
void func2();
B bb;
};
void A::func(){
bb.setx(100);
bb.show();
}
void A::func2(){
bb.show();
}
int main()
{
A a;
B b;
a.func();
b.show();
a.func2();
return 0;
}
Changes are applicable only to class A, where actual value in class B is not changing. I tried static but its showing error.
OUTPUT I'M GETTING :
Inside set 100
inside show 100
inside show 0
inside show 100
OUTPUT I WANT :
Inside set 100
inside show 100
inside show 100
inside show 100

Try:
int main()
{
A a;
B b;
a.func();
a.bb.show();
a.func2();
return 0;
}
You're calling show() on wrong object. Since a has it's own bb, you need to use a.bb to see change. b in main is different object (even if of the same class).

A class is not an object. It is a user defined data type which can be accessed and used by creating an instance of that class. An instance of the class is an object.
Now, in your main function, when you instantiate an object of class A by writing A a;, the constructor of class A instantiates the data member bb (which is of type B). You then create another object of type B in your main function, by writing B b;. This instantiation of class B has nothing to do with the data member bb in your class A. To get your desired output, you would need a.bb.show().
To be clear:
struct Airplane {};
Airplane a1, a2, a3;
I have 3 airplanes, which are each an instantiation of the class Airplane, 3 objects of type Airplane. Changing a1 doesn't imply changing a2 and a3.

Related

C++ general question on OOP Design, how to access member of object in the top of hierarchy from bottom

I have a Class A, in the class there is some important member (lets call it someVeryImportantNumber) and also objects of class B. In class B there are objects of class C and so on..., similar to a tree structure (could be 4, 10, or 20 levels of such objects.)
How could i get access to someVeryImportantNumber from the bottom of the hierarchy (to access someVeryImportantNumber from class D).
I was thinking about passing the number down the hierarchy, but this seems not very effective approach when i have lets say 10 or more of levels hierarchy.
Is there some smarter way to do it? I looked at dependency injection but it is not the way to go for me...
Any suggestions? Thank you...
class D {
public:
void foo() {
// need to use someVeryImportantNumber here
}
}
class C {
public:
D d1;
D d2;
D d3;
}
class B {
public:
C c1;
C c2;
}
class A {
public:
int someVeryImportantNumber = 1234;
B b;
}
int main() {
A a;
return 0;
}
You can use a reference to avoid copying that someVeryImportantNumber, and pass it through the constructors:
class D {
const int& someVeryImportantNumber_;
public:
D(const int& someVeryImportantNumber) : someVeryImportantNumber_(someVeryImportantNumber) {}
void foo() {
// need to use someVeryImportantNumber here
}
}
class C {
public:
C(const int& someVeryImportantNumber)
: d1(someVeryImportantNumber), d2(someVeryImportantNumber), d3(someVeryImportantNumber) {}
D d1;
D d2;
D d3;
}
class B {
public:
B(const int& someVeryImportantNumber)
: c1(someVeryImportantNumber), c2(someVeryImportantNumber) {}
C c1;
C c2;
}
class A {
public:
A() : b(someVeryImportantNumber) {}
int someVeryImportantNumber = 1234;
B b;
}
int main() {
A a;
return 0;
}
You cannot do what you're asking.
The reason is simple: in your example, D is contained in C as 3 separate instances, and there is no way to tell, from an object of type D, which instance it belongs to (d1, d2, or d3).
On the other hand, you could access the container instance through something like container_of macro, provided that you also know which instance D belongs to. See https://radek.io/2012/11/10/magical-container_of-macro/. Notice that container_of is used in C but it works in C++ as well.
For instance, if you know that your D is accessed from C::d1, you could use container_of(this, C, d1) to access the instance of C and then reiterate the procedure to access B and then A.
But remember, there is no way to know at run time which one of the 3 instances of D your this pointer refers to, unless you somehow encode the information in your classes.

using derived class data members from base class method

So i have been trying to use derived class data members from the base class and i am not able to figure out how to do that. I see a way to do this as just passing the member i need in parameter when i call the base class method but i was just thinking that there should be another way to do that. So i have replicated this as below.
#include<iostream>
using namespace std;
class B;
class A{
public:
display(){
cout<<cord<<endl;
}
int cord = 25;
};
class B : public A{
public:
B(){
A a;
a.display();
}
int cord = 30;
};
class C : public A{
public:
C(){
A a;
a.display();
}
int cord = 35;
};
int main(){
B b;
C c;
B.display();
}
The above code as giving output as
25
25
25
What i want it to give out is
30
35
30
Every way to do this will be appreciated, whatever is better and if you want to me add something or anything ask in comments, i'll do right away.
define a virtual getter like
virtual int getCord() const { return cord; }
in each class and call it in display
void display(){ cout << getCord() <<endl; }
and in the constructor of B and C you also need to replace
A a;
a.display();
just by
display();
else there is no chance you access to the value of the sub classes explicitly calling display on an instance of A
using derived class data members from base class method
This is because of that I let the redefinition of cord in B and C, but I do not recommend you to do that kind of redefinition in 'real' codes ;-)
Lets take the B constructor:
B(){
A a;
a.display();
}
In it you create a completely separate object a of type A, and call display on it. That display call will be using the a object, not knowing anything about the B class or its totally separate cord member variable at all.
One possible way to solve this is to create a constructor of A that takes the value of cord as an argument, pass the "correct" value in the B constructor initializer list, and then call the display function on this object:
struct A{
A() = default;
explicit A(int c)
: cord(c)
{
}
display(){
cout<<cord<<endl;
}
int cord = 25;
};
struct B : A{
B()
: A(30)
{
display(); // Equivalent to this->display();
}
};
Of course, you need to do something similar for the C class (or structure).
Note that I removed the member variable cord from the B class. That's because if you declare a new member variable with the same name as a member variable in a base class, then you effectively create a completely new member variable that is unrelated to the one in the parent class. And for the simple example you show there's no need to "override" the member variable, as it already exists in all child-classes as well.

C++ Have two child classes share a variable from their base class

So say I have 3 classes: Base, A, and B.
Base is a base class for both class A and class B.
Base has a variable val that A and B can access.
How would I get it to work where I can set the val variable through class A, and it is reflected in class B?
For example:
I know this code below won't work because I am creating an OBJECT of the type a and b.
What I want to do is to simply have a and b share the same variable so that whenever a does something to it, it is reflected in b.
a aa;
b bb;
aa.SetVal(50000);
cout << aa.GetVal() << endl;
cout << bb.GetVal() << endl;
In the end I'd want both cout lines to print out 50000.
EDIT: The classes A and B will be doing different operations and just need to be able to access/change the val variable in base
You could make the member a static member of the base class, then all derived classes could access it, however any object of a derived that changes the static member would change it for every other object.
class Base
{
public:
int GetVal()
{
return val;
}
void SetVal( int newVal )
{
val = newVal;
}
private:
static int val;
};
// Need to instantiate the static variable somewhere
int Base::val = 0;
class A : public Base
{};
class B : public Base
{};
class Base {
static int value;
public:
virtual ~Base() { }
void setVal(const int& val) {
value = val;
}
int getVal() const {
return value;
}
};
int Base::value = 0;
class A : public Base {
};
class B : public Base {
};
#include <iostream>
int main() {
A a;
B b;
a.setVal(20);
std::cout << b.getVal(); // 20
}
That's a job for references, not for classes. Just have one class X and create a reference to the object:
X aa;
X& bb = aa;
aa.SetVal(50000);
std::cout << aa.GetVal() << std::endl;
std::cout << bb.GetVal() << std::endl;
The output will be:
50000
50000
Remember to always use the right tool for the job and keep things simple.
The main goal is that those two classes will be doing different things but will need to be able to access and share a single variable.
An idea to solve this is to extract the common variable in another class, namely S, which will be passed to A and B like this:
std::shared_ptr<S> s = new S();
A aa(s);
B bb(s)
Now, both aa and bb share the same S object and can modify it very easily. Notice that the constructor of both A and B should store the std::shared_ptr<S> as well:
class A { // and B
private:
std::shared_ptr<S> s;
public:
A(std::shared_ptr<S> as) : s(as) {}
};
The variable s will last as long as any of aa and bb is alive: when both aa and bb gets deallocated or go out of scope, the variable s will be deallocated as well.
If the type of the common variable should be on the stack, you can also just use references, but watch out for the lifetime of aa, bb and that variable:
int s = 0;
A aa(s);
B bb(s);
with:
class A { // and B
private:
int& s; // or any other type
public:
A(int& as) : s(as) {}
};
But as a general rule of thumb I'd avoid shared state between objects. Most of the time, depending on the context, you can refactor your code and get rid of the shared dependency.
If the shared value is static in the base class, then all instances of derived classes will see exactly that one base class member.
If the value is not static, then each instance of a class will have its own copy whether or not the value is in a base class.
Not sure I understand what you are trying to do. Do you want all instances of A and B to share the same value? if so, declare it as static in the base class.
if not, how do you want to choose which one will share the value?

Heterogeneous Lists, Virtual Functions, and Member Data

I'm having some trouble figuring out how to assign values to member data when calling a virtual function through a heterogeneous list.
Here's an example of what I'm trying to do:
class A
{
protected:
virtual void func1();
private:
A * list;
}
class B: public A
{
protected:
void func1();
private:
int i1, i2;
}
Within main():
list = new A[10];
list[0] = new B;
list[0]->Func1();
Declaration of Func1():
void B::Func1()
{
int a, b;
cin >> a >> b;
list[0]->i1 = a;
list[0]->i2 = b;
// or can I just do this:
// i1 = a;
// i2 = b;
}
I'm looking for the appropriate way to access member data of a derived class within a function of the derived class if calling via a pointer of the parent class from main. Any help would be much appreciated!
While executing a virtual function you now that the type of the object is the type of class the function is defined in or a class derived thereof. That is, in your B::func1() function you know this points to a B object. The object may be of a type derived fromB but you still have everything present in B.
On the other hand, you don't know statically that list[0] points to B object. The code you have uncommented in your code does not work. The commented code looks OK

How to call a method in one object from another object in the same structure

I have the following situation:
class B
{
public:
void methodInB();
};
class C
{
public:
void methodInC();
};
class A
{
public:
void methodInA();
private:
B objB;
C objC;
};
void A::methodInA()
{
objB.methodInB();
}
int main()
{
A objA;
objA.methodInA();
return 0;
}
I want to be able to call C::methodInC() from within B::methodInB(), but I'm not sure what the way to go about it would be (not without messing with globals).
My first idea was to add a C* pC pointer as a member of B, and then from methodInB() call it as pC->methodInC. This would require I set the pointer from within A before using the method (possibly in A's constructor). My problem is I may need to call other objects from within B if I add a D and E objects, and I don't want to fill the class definition with pointers.
Is there some other way of doing this? An implicit reference to the object the object belongs to? Kind of like this but for the parent? So I could at least do parent->objC->methodInC()?
I think the cleanest way would be to "inject the dependency", that is, to pass objC to methodInB, which would then invoke methodInC on that object:
void A::methodInA()
{
objB.methodInB(objC);
}
// ...
void B::methodInB(C &objC)
{
objC.methodInC();
}
Let every class B, C, D, E, etc. have a pointer to the A object of which they are subobjects.
class A;
class C;
class B
{
A* pA;
void MethodB();
};
...
void B::MethodB
{
(pa->CObject).MethodC();
}