How do I call the copy constructer here.

T

Tony Johansson

Hello!!

Here I have two class definitions.

Here is the copy constructorn for class String. I know that the last part in
the initialization list is wrong which is
this part myBody(s.myBody) because this just assign a pointer to anothert
pointer. I just wonder how should this
part be written if I want to call the copy constructor in class StringRep
from the copy constructor of class String.

//Tony

String(const String& s) : myBody(s.myBody)
{ myBody->refCount; }

class StringRep
{
private:
char* myChars;
int refCount;

StringRep()
{ myChars = new char(10); }

StringRep(const StringRep& sr) : refCount(1)
{ }

friend class String;
};

class String
{
private:
StringRep* myBody;
public:
String()
{ myBody = new StringRep; }

String(const String& s) : myBody(s.myBody)
{ myBody->refCount; }

~String()
{
if (--myBody->refCount == 0)
delete myBody;
cout << myBody->refCount;
}
};
 
V

Victor Bazarov

Tony said:
Here I have two class definitions.

Here is the copy constructorn for class String. I know that the last
part in the initialization list is wrong which is
this part myBody(s.myBody) because this just assign a pointer to
anothert pointer.

Why is that wrong?
I just wonder how should this
part be written if I want to call the copy constructor in class
StringRep from the copy constructor of class String.

Before we continue, just a note, so that we're clear on terminology.
You _cannot_ call any constructor. Plain and simple.

That said, you _can_ construct another object [dynamically] and make
it copy-constructed from the one pointed to by 's.myBody', if you
use

myBody(new StringRep(*s.myBody))

but I am not at all convinced that it's what you should be doing.
//Tony

String(const String& s) : myBody(s.myBody)
{ myBody->refCount; }

class StringRep
{
private:
char* myChars;
int refCount;

StringRep()
{ myChars = new char(10); }

This is bogus. Should probably be

myChars = new char[10];

.. And move it to the initialiser list.
StringRep(const StringRep& sr) : refCount(1)
{ }

'myChars' is *not* being copied here. You forgot to initialise it
at all, and that means it's left _uninitialised_.
friend class String;
};

class String
{
private:
StringRep* myBody;
public:
String()
{ myBody = new StringRep; }

Again, this is much better located in the initialiser list.
String(const String& s) : myBody(s.myBody)
{ myBody->refCount; }
^^^^^^^^^^^^^^^^^
I an not sure what this statement is doing there. Is there a point
to it or is it there just for debugging purposes?
~String()
{
if (--myBody->refCount == 0)
delete myBody;
cout << myBody->refCount;

Are you sure you should be manipulating 'refCount' yourself here?
Shouldn't it be the task of 'myBody' to count its own references?

I strongly recommend you to take a good look at ref-counting string
(or anything else) implementation in the literature. Learn by using,
not by re-inventing the wheel. You can much sooner understand how
it works and even improve it when you begin from something that is
already working.

V
 
D

Donovan Rebbechi

Hello!!

Here I have two class definitions.

Here is the copy constructorn for class String. I know that the last part in
the initialization list is wrong which is
this part myBody(s.myBody) because this just assign a pointer to anothert
pointer.

No, that's correct. You just assign a pointer.
I just wonder how should this
part be written if I want to call the copy constructor in class StringRep

If you want to do that, you don't need the reference count. You would do something
like

String ( const String& s) : rep (s.rep) {}

or

String ( const String& s) : rep(new StringRep(s.rep)) {}

from the copy constructor of class String.

//Tony

String(const String& s) : myBody(s.myBody)
{ myBody->refCount; }

This is wrong. You need to increase the reference count. The expression
myBody->refCount
does not increase the count or do anything.

You probably meant something like
++myBody->refCount;

Cheers,
 
R

Rolf Magnus

Victor said:
^^^^^^^^^^^^^^^^^
I an not sure what this statement is doing there. Is there a point
to it or is it there just for debugging purposes?

I think this should have been: myBody->refCount++;
Are you sure you should be manipulating 'refCount' yourself here?
Shouldn't it be the task of 'myBody' to count its own references?

How would it do that?
 
M

Michael Kochetkov

Are you sure you should be manipulating 'refCount' yourself here?
How would it do that?
There are only three places where manipulating with counted references takes
(shall take) places: constructors, destructors and assignment operators. The
general approach is when you have a Reference class that controlles the
counter and mutexes if needed and a CountedReference class that handles its
Reference object.
class AImp : public Reference {...};
template<class T>
CountedReference {
T* imp_;
....
};

class A {
CountedReference <AImp> imp_;
....
};

It is a common practice when neither A nor AImp take care about reference
counter, mutexes, memory pool or anything else that can take plase. Such
awareness may appear to be very expensive when you decide to switch your
objects to a memory dispatcher of your own, for example, or to add a
multithreding support.
 

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,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top