Object Composition & Returning References....

P

Patrick

I want to achieve the following behaviour but I am having trouble
getting there...bare with me im knew to c++ , so its probably rather
trivial!

To have a class ClassA, and composed within this class is an instance
of another class, ClassB.
I want to have a method getClassB that returns a reference to the
instance of ClassB composed within ClassA.
So when a client calls getClassB they are supplied with a reference to
the instance of ClassB composed within ClassA, so that any
modifications that the client makes to this reference are mirrored in
the instance composed within ClassA.

So far I have constructed ClassA, ClassB, and managed to have an
instance of ClassB composed within ClassA.

My problem is with the "getClassB" method. I have only managed to be
able to return a pointer to the instance of ClassB composed within
ClassA. I want to be able to return a reference (&) not a pointer (*).

The instance of ClassB composed within ClassA is initialised in the
constuctor using
classB = new ClassB(9);
so I have to store it within the class as a pointer i.e.
class ClassA
{ public:
ClassA();
~ClassA();
ClassB* getClassB();

private:
ClassB *classB;
};
then when i go to implement the getClassB method I cannot figure out
how to return a reference.

Is there a way of returning a reference givin that I store classB as a
pointer?
Or do I need to store classB differently? I have tried derefenceing
the pointer return by the "classB = new ClassB(9);" and storing it
explicitly but this didnt seam to work.

The full listing of the code is below with a test file, I want to
maintain the same behaviour as is present at the moment, but using
references instead of pointers in the getClassB method.

That is i want to replace

ClassB* ClassA::getClassB()
{ return classB;
}

with

ClassB& ClassA::getClassB()
{ return classB;
}

any help/pointers greatly appreciated.

pat
----------------------------------------------------------
//Main.cpp

#include <iostream>
#include <cstdlib>
#include "ClassA.h"
#include "ClassB.h"

using namespace std;

int main(int argc, char *argv[])
{
ClassA a;
ClassB *b = a.getClassB();
cout << "a.getClassB() = " << *(a.getClassB()) << "\n";
cout << "b = " << *b << "\n";

b->setValue(0);

cout << "\n\nAfter : b.setValue(0)\n";
cout << "a.getClassB() = " << *(a.getClassB()) << "\n";
cout << "b = " << *b << "\n";

a.getClassB()->setValue(4);
cout << "\n\nAfter : a.getClassB().setValue(4)\n";
cout << "a.getClassB() = " << *(a.getClassB()) << "\n";
cout << "b = " << *b << "\n";

system("Pause");
return 0;
}

----------------------------------------------------------
//ClassA.h

#ifndef CLASSA_H
#define CLASSA_H

#include "ClassB.h"

using namespace std;

class ClassA
{ public:
ClassA();
~ClassA();
ClassB* getClassB();

private:
ClassB *classB;
};

#endif

----------------------------------------------------------
//ClassA.cpp

using namespace std;

#include "ClassA.h"
#include "ClassB.h"

ClassA::ClassA()
{ classB = new ClassB(9);
}

ClassA::~ClassA()
{ delete classB;
}

ClassB* ClassA::getClassB()
{ return classB;
}

----------------------------------------------------------
//ClassB.h

#ifndef CLASSB_H
#define CLASSB_H
#include <iostream>

using namespace std;
class ClassB
{ friend ostream& operator<<(ostream& , const ClassB&);

public:
ClassB(int value);
void setValue(int value);

private:
int value;
};

#endif

----------------------------------------------------------
//ClassB.cpp

#include "ClassB.h"

ClassB::ClassB(int value)
{ (*this).value = value;
}

void ClassB::setValue(int value)
{ (*this).value = value;
}

ostream& operator<<(ostream& output, const ClassB& object)
{ output << object.value;
return output;
}


----------------------------------------------------------
 
J

John Harrison

Patrick said:
I want to achieve the following behaviour but I am having trouble
getting there...bare with me im knew to c++ , so its probably rather
trivial!

To have a class ClassA, and composed within this class is an instance
of another class, ClassB.
I want to have a method getClassB that returns a reference to the
instance of ClassB composed within ClassA.
So when a client calls getClassB they are supplied with a reference to
the instance of ClassB composed within ClassA, so that any
modifications that the client makes to this reference are mirrored in
the instance composed within ClassA.

So far I have constructed ClassA, ClassB, and managed to have an
instance of ClassB composed within ClassA.

My problem is with the "getClassB" method. I have only managed to be
able to return a pointer to the instance of ClassB composed within
ClassA. I want to be able to return a reference (&) not a pointer (*).

The instance of ClassB composed within ClassA is initialised in the
constuctor using
classB = new ClassB(9);

Do you have a good reason for doing it this way? Its generally better to
avoid pointers, if you can.
so I have to store it within the class as a pointer i.e.
class ClassA
{ public:
ClassA();
~ClassA();
ClassB* getClassB();

private:
ClassB *classB;
};
then when i go to implement the getClassB method I cannot figure out
how to return a reference.

Simple

ClassB& getClassB() { return *classB; }

john
 
P

Patrick

Thanks for the reply

I had implemented getClassB as you suggested, but when i was doing the
following in the code that called it

ClassB b = a.getClassB();

I understand now that the "copy" constructor was being used here,
right?

How can i (or is it possible to) implement the getClassB() method s.t.
when i do the following

ClassB b = a.getClassB();

i am not using the copy constructor, and "b" refers to the instance of
ClassB composed within ClassA, not a copy of it.
Do you have a good reason for doing it this way? Its generally better to
avoid pointers, if you can.

Yes i think so, but could be wrong, this is just a toy example to help
me figure out how to get it working.

My ClassA will store a Vector of (references to) ClassB objects.
ClassA will allow the client add and delete ClassB objects from this
Vector.
And I need to be able to return a reference to this Vector from ClassA
to the client.
So I was trying to figure out how to get it working with just an
instance of ClassB composed within ClassA, then i will hopefully
understand how to get it working with a Vector containing instances of
ClassB. Maybe its just as easy as my example at the moment.

much appreciated.

pat
 
J

John Harrison

Patrick said:
Thanks for the reply

I had implemented getClassB as you suggested, but when i was doing the
following in the code that called it

ClassB b = a.getClassB();

I understand now that the "copy" constructor was being used here,
right?

How can i (or is it possible to) implement the getClassB() method s.t.
when i do the following

ClassB b = a.getClassB();

i am not using the copy constructor, and "b" refers to the instance of
ClassB composed within ClassA, not a copy of it.

Use a reference

ClassB& b = a.getClassB();

but remember that you cannot 'reseat' references, i.e. if later you do

b = a2.getClassB();

that will not make b refer to the ClassB object in a2, instead it will copy
the a2 ClassB to the a ClassB (which b will still refer to).

If you think you might need to change where a variable refers to, you are
better of using pointers than references.

john
 
P

Patrick

Just for the record, this is what i was trying to do.
It looks right, it seems to work right, so hopefully its gotta be
right, right?

pat


------------------------------------------------------------------------
//main.cpp
#include <iostream>
#include <cstdlib>
#include "ClassA.h"
#include "ClassB.h"

using namespace std;

int main(int argc, char *argv[])
{
ClassA a;
ClassB b1(1);
ClassB* b2 = new ClassB(2);
ClassB b3(3);

//adding element to vector composed within instance of ClassA
a.addElement(b1);

//making a reference to vector composed within instance of ClassA
vector<ClassB>& classBVec2 = a.getClassBVec();

//altering an object in the vector composed within instance of ClassA,
//via reference to it
classBVec2[0].setValue(11);

//altering the vector composed within instance of ClassA,
//via reference to it
classBVec2.push_back(*b2);

//altering the vector composed within instance of ClassA,
//via reference to it
classBVec2.push_back(b3);

system("Pause");
return 0;
}
------------------------------------------------------------------------
//ClassA.h

#ifndef CLASSA_H
#define CLASSA_H
#include <vector>

#include "ClassB.h"

using namespace std;

class ClassA
{ public:
ClassA();
void addElement(ClassB& element);
vector<ClassB>& getClassBVec();

private:
vector<ClassB> classBVec;
};

#endif

------------------------------------------------------------------------
//ClassA.cpp

using namespace std;
#include "ClassA.h"

ClassA::ClassA()
{
}

void ClassA::addElement(ClassB& element)
{ classBVec.push_back(element);
}

vector<ClassB>& ClassA::getClassBVec()
{ return classBVec;
}

------------------------------------------------------------------------
//ClassB.h

#ifndef CLASSB_H
#define CLASSB_H
#include <iostream>

using namespace std;
class ClassB
{ friend ostream& operator<<(ostream& , const ClassB&);

public:
ClassB(int value);
void setValue(int value);

private:
int value;
};

#endif

------------------------------------------------------------------------
//ClassB.cpp

#include "ClassB.h"

ClassB::ClassB(int value)
{ (*this).value = value;
}

void ClassB::setValue(int value)
{ (*this).value = value;
}

ostream& operator<<(ostream& output, const ClassB& object)
{ output << object.value;
return output;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top