i tried to make this:
#include <iostream>
#include <memory>
class B
{
public:
std::string var;
B()
{
var = "original";
}
void print()
{
std::cout << "composition " << std::endl;
}
};
class A
{
public:
int a_attribute = 10;
std::unique_ptr<B> b;
};
int main()
{
A a;
a.b->print();
}
That seems to work fine, except when i try to access the attributes of B, with e.g:
std::string test = a.b->var;
which leads to segmentation fault
error
why i'm not getting an error to a.b->print();
but getting segfault to a.b->var;
?
CodePudding user response:
You problem is here, in A you have
std::unique_ptr<B> b;
this creates a smart pointer to a B object. But it there is no B object that it points at. Before you can use it you must create a B object and set 'b' to point at it.
I dont know exactly how and when you want to create your B but you can do this
A a;
a.b = std::make_unique<B>();
a.b->print();
this will create a new B using the default contructor and make 'a.b' point at it. This is more effiecient short hand for
A a;
B *b1 = new B;
a.b.reset(b1);
a.b->print();
which explicitly creates a B and then sets a.b to point at it.
Note that you do not have to free the B object. Thats the point of smart pointers they will do it for you.
You asked why some combinations work and some dont.
You had Undefined Behavior. This can do anyting , including worst of all, appearing to work. Then at midnight on Christmas eve your largest customer submits a huge order to your system and it crashes. Every professional dev has had some occurrence of this. Ways to avoid: crank up the compiler warning levels, never ignore warnings. Use a tool like valgrind or other commercial checker tools.
For me your original code as posted worked. Why, because the invoked method doesnt actually need any data in the B object. But If I change to this
void print()
{
std::cout << "composition " << std::endl;
std::cout << var << std::endl;
}
it fails because now we are referencing data in the B object, but there isn't one.
Note that on a different compiler your original code will not work