Probably an easy question for someone out there, but what am I doing wrong in the below example? I'm trying to build a global class which contains instantiations of other classes within... I think where I'm going wrong boils down to the below example. Getting a seg fault, as if *b is never created. Thanks in advance!!
#include <iostream>
using namespace std;
class A;
class B;
class B
{
public:
B()
{
b = 99;
}
~B();
int Getb() {return b; }
void Setb (int x) { b = x; }
private:
int b;
};
class A
{
public:
A()
{
B *b = new B;
}
~A();
B * b;
void Printout()
{
cout<<b->Getb()<<endl;
}
private:
};
int main()
{
A *a = new A;
a->Printout();
cin.get();
}
In the cosntructor
A::A()
you don't initilize theA::b
member, but a local variable instead. Try doing:or better:
And even better, don't use the raw pointer at all.
In the constructor you're declaring a new local variable that gets assigned the address of the freshly allocated
B
, and then forgotten!The instance field
b
is never assigned to because it is shadowed by the local variable of the same name in the constructor.You probably mean to do
Great tips guys, even though in retrospect I obfuscated my issue with naming the int variable b (should've been anything but b!!). That said, you guys "pointed" me in the direction to initialization lists, destructors, and ultimately to the topic of composition. Many thanks How to implement class composition in C++?
Although quite a few people have pointed out one way of fixing the problem you're seeing, none seems (to me, anyway) to be giving advice about how to really make the code better.
Your definition of
B
is what's called aquasi-class
. To make a long story short, yourB
can be simplified a lot without losing anything:Everything else you've done (get/set, destructor) are accomplishing absolutely nothing. Your
A
class not only accomplishes just about as little, but does it even more poorly. Others have already pointed out the problem withA
's constructor defining a localB
object, and then leaking that object. None (that I've seen yet, anyway) has pointed out that even when you fix that, your definition ofA
will leak theB
object anyway, because even though it creates aB
object as part of creating anA
object, it does not destroy theB
object when theA
object that contains it is destroyed.I don't see any reason for your
A
class to dynamically allocate theB
object at all (or, when you get down to it, to even exist). I'd defineA
more like this:It would be better, however, if a
B
object knew how to insert itself into a stream -- and if it used the normal syntax for that as well:With this in place, your
A
class adds nothing at all, so your entire program becomes something like this:Creates a local variable named
b
which shadows the class memberb
. You need to initialize the class member, and you should do it in an initialization list.Your next step is to fix the memory leak caused by never calling
delete
on the pointers you dynamically allocate, but since this is a learning exercise it's probably not terribly important (yet).should be
In your version there a variable called b in the A constructor. This variable hides the A class member also called b (which was obviously the one you wanted to use).