-
Request for help
Code:
#include <iostream>
using namespace std;
class B
{
public:
int value;
B(){
value = 10;
}
~B(){
}
void funcB(){
value = 135;
}
};
class A
{
public:
A() {
B* objB1 = new B;
cout << "Print inside A class == " << objB1->value << endl;
}
~A() {}
};
int main()
{
B* objB = new B;
objB->funcB();
A* objA = new A;
return 0;
}
Hello Everybody, Once I print the objB1->value inside of "A" class, It always provide the output 10 regardless of 135. Why?
-
You are creating two instances of class "B", one owned by main, the other owned by class A.
-
Hi Malcolm, thanks for the answer. If I want to share the updated value of object owned by main to the object owned by class A, what should I do?
-
Especially if you don't want to have to delete what you new, then perhaps you should not use new if you can avoid it. In this case perhaps an example like this would suffice:
Code:
#include <iostream>
using namespace std;
class B
{
public:
int value = 10;
void funcB() {
value = 135;
}
};
class A
{
public:
explicit A(B& objB1) : objB(&objB1) {
cout << "Print inside A class == " << objB->value << endl;
}
void funcA() {
cout << "A::funcA() presumably uses its B member in some way: " << objB->value << endl;
}
private:
B* objB;
};
int main()
{
B objB;
cout << "objB.value = " << objB.value << endl;
objB.funcB();
A objA{objB};
objA.funcA();
return 0;
}
So the idea is that main (or some other function or object) owns the B object, then you pass a reference to the B object when creating the A object. The newly created A object stores a pointer to that B object via the reference as a member so it can continue to access the B object. As long as you don't play around with copying (e.g., you disable it), this is quite safe: the B object must exist before the A object, so you don't worry about the B object silently getting destroyed. If you do copy (or move, but moving is no advantage since either way you just need to copy the member pointer), then there's the risk that you can copy the B pointer to an A object that exists before the B object, and hence when the B object is destroyed, the A object's B pointer is silently invalidated although it continues to exist. For example:
Code:
int main()
{
B objB1;
A objA1{objB1};
objA1.funcA(); // perfectly fine
{
B objB;
objB.funcB();
A objA{objB};
objA1 = objA;
}
objA1.funcA(); // undefined behaviour due to the access of an invalid pointer
return 0;
}
You might get this output:
Code:
Print inside A class == 10
A::funcA() presumably uses its B member in some way: 10
Print inside A class == 135
A::funcA() presumably uses its B member in some way: 135
But in fact the last line of output is the result of undefined behaviour, and in more complex scenarios such that the memory previously used by the B object gets reused and overwritten, you could find that the output is unexpected.
-
Thanks Amanda for a nice explanation. Now It is clear to me. Thanks again.