A question on initialize a object with a pointer

P

PengYu.UT

Hi,

Suppose I have the following class declaration with a pointer as the
argument. And suppose I "new" an array "lengths" as the argument
"edge_lengths". Now, the polygon object is valid. Unfortunately, it
becomes invalid after I delete "lengths" array be mistake.

My question is that using object, the object's(an polygon object in
this case) internal states are encapsulated. They should not be affect
by anything operations unless the member operator. But the above
example shows that the object's internal states can be affected if
pointers are used. I'm wondering if there are any solutions to fix it.

class polygon{
public:
polygon(int edge_lengths[], int edge_count) :
_edge_lengths(edge_lengths),_edge_count(edge_count) {}
}
private:
int *_edge_lengths;
int _edge_count;
};


Best wishes,
Peng
 
J

Jordan

You are performing a shallow copy in the class'es member initializer
list. This means that the only thing that gets copied over is the
array's address which as you mentioned can be deleted outside of the
class'es encapsulation. What you will need to do is implement the
contructor to perform a deep copy meaning you make a new local array
and copy the contents over.

For example...

class polygon
{
public:
polygon( int edge_lengths[], int edge_count ) :
_edge_count(edge_count)
{
_edge_lengths = new int[edge_count];
for( int index = 0; index < edge_count; index++ )
{
_edge_lengths[index] = edge_lengths[index];
}
}

~polygon() { if( _edge_lengths) delete [] _edge_lengths; }

private:
int *_edge_lengths;
int _edge_count;
};

Does this make sense? You want to copy all of the values from the one
array into the new array. Now here is the catch, you are going to need
to make sure you add a destructor to your polygon class to deallocate
the new array, and you need to make sure that whatever is in the array
supports the "=" operator so the deep-copy assignes correctly.

I hope that helps.
 
K

Kai-Uwe Bux

Hi,

Suppose I have the following class declaration with a pointer as the
argument. And suppose I "new" an array "lengths" as the argument
"edge_lengths". Now, the polygon object is valid. Unfortunately, it
becomes invalid after I delete "lengths" array be mistake.

My question is that using object, the object's(an polygon object in
this case) internal states are encapsulated. They should not be affect
by anything operations unless the member operator. But the above
example shows that the object's internal states can be affected if
pointers are used. I'm wondering if there are any solutions to fix it.

class polygon{
public:
polygon(int edge_lengths[], int edge_count) :
_edge_lengths(edge_lengths),_edge_count(edge_count) {}
}
private:
int *_edge_lengths;
int _edge_count;
};


Best wishes,
Peng

what about


class polygon {
public:

template < typename IntIterator >
polygon ( IntIterator from, IntIterator to )
: length_vector( from, to )
{}

private:

std::vector< int > length_vector;

};

now use length_vector[...] to access a length, and use length_vector.size()
to get the number of edges.


Best

Kai-Uwe Bux
 
I

Ian

Hi,

Suppose I have the following class declaration with a pointer as the
argument. And suppose I "new" an array "lengths" as the argument
"edge_lengths". Now, the polygon object is valid. Unfortunately, it
becomes invalid after I delete "lengths" array be mistake.

My question is that using object, the object's(an polygon object in
this case) internal states are encapsulated. They should not be affect
by anything operations unless the member operator. But the above
example shows that the object's internal states can be affected if
pointers are used. I'm wondering if there are any solutions to fix it.
What's the point in trying to encapsulate an external object (your
lengths array)? If you want to encapsulate it and make your object
safe, copy it.

Or hold it in a smart pointer object and pass that.

Ian
 
P

PengYu.UT

Jordan said:
You are performing a shallow copy in the class'es member initializer
list. This means that the only thing that gets copied over is the
array's address which as you mentioned can be deleted outside of the
class'es encapsulation. What you will need to do is implement the
contructor to perform a deep copy meaning you make a new local array
and copy the contents over.

For example...

class polygon
{
public:
polygon( int edge_lengths[], int edge_count ) :
_edge_count(edge_count)
{
_edge_lengths = new int[edge_count];
for( int index = 0; index < edge_count; index++ )
{
_edge_lengths[index] = edge_lengths[index];
}
}

~polygon() { if( _edge_lengths) delete [] _edge_lengths; }

private:
int *_edge_lengths;
int _edge_count;
};

Does this make sense? You want to copy all of the values from the one
array into the new array. Now here is the catch, you are going to need
to make sure you add a destructor to your polygon class to deallocate
the new array, and you need to make sure that whatever is in the array
supports the "=" operator so the deep-copy assignes correctly.

I hope that helps.

I could you use deep copy. But the problem with it is that it might be
very expensive in terms of memory usage and run time. For performance
sake, sometimes it is better to use pointer, right? My question is how
to use pointer without exposing too much internal information of
objects. Thanks!
 
J

Jordan

Typically, yes. Depending on what you are storing within your polygon
class (i.e. the number of polygons) it may be too expensive to perform
a deep-copy. In this case, a pointer is the way to go. However, you
might want to consider changing your design slightly.

Why are you keeping an instance within the object and one outside of
the object? If you want to be truly OOP, provide a method within the
polygon object to load your polygons and manage them internally. This
way you won't unneccessarily expose your pointers.

If you do not want to do that, do not keep a reference to the pointer
within the class. Just use the class'es members to operate on the
polygons but not hold them. Do you know what I mean?

The better option would probably be to have a polygon manager class
that handles the loading and processing of the polygons internally.
 
P

PengYu.UT

Jordan said:
Typically, yes. Depending on what you are storing within your polygon
class (i.e. the number of polygons) it may be too expensive to perform
a deep-copy. In this case, a pointer is the way to go. However, you
might want to consider changing your design slightly.

Why are you keeping an instance within the object and one outside of
the object? If you want to be truly OOP, provide a method within the
polygon object to load your polygons and manage them internally. This
way you won't unneccessarily expose your pointers.

If you do not want to do that, do not keep a reference to the pointer
within the class. Just use the class'es members to operate on the
polygons but not hold them. Do you know what I mean?

The better option would probably be to have a polygon manager class
that handles the loading and processing of the polygons internally.

Currently, I'm reading GoF's Design Pattern book. I'm wondering if
there is any design pattern as you mentioned.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top