Exception

N

Nindi

I have just been looking again at http://www.gotw.ca/gotw/059.htm

What is wrong with a solution like :


class MyClass {
public:

MyClass():theA(...),theB(...){...}

MyClass(const MyClass
&theOther):theA(theOther.theA),theB(theOther.theB){...}

MyClass& operator=(const MyClass &theOther)
{
MyClass temp(theOther);
swap( (void *)(&theA),(void *)(&temp.theA),sizeof(InnerObject));
swap( (void *)(&theB),(void *)(&temp.theB),sizeof(InnerObject));

return *this;

}
static void swap(void *b,void *a,int count)
{
char temp;
for(int i(0);i<count;++i){
temp=((char*)(a));
((char *)(a)) = ((char *)(b));
((char *)(b))=temp;
}

}

InnerObject theA;
InnerObject theB;
};

to part 3 ?
 
A

Alan Johnson

Nindi said:
I have just been looking again at http://www.gotw.ca/gotw/059.htm

What is wrong with a solution like :


class MyClass {
public:

MyClass():theA(...),theB(...){...}

MyClass(const MyClass
&theOther):theA(theOther.theA),theB(theOther.theB){...}

MyClass& operator=(const MyClass &theOther)
{
MyClass temp(theOther);
swap( (void *)(&theA),(void *)(&temp.theA),sizeof(InnerObject));
swap( (void *)(&theB),(void *)(&temp.theB),sizeof(InnerObject));

return *this;

}
static void swap(void *b,void *a,int count)
{
char temp;
for(int i(0);i<count;++i){
temp=((char*)(a));
((char *)(a)) = ((char *)(b));
((char *)(b))=temp;
}

}

InnerObject theA;
InnerObject theB;
};

to part 3 ?


Let's say InnerObject looks something like:
class InnerObject
{
private:
unsigned char data[1024] ;
unsigned char * block1 ;
unsigned char * block2 ;
public:
// Various members ...
} ;

Assume at any given time, 'block1' and 'block2' point to some location
within 'data'. Swapping in the manner you propose would now create
InnerObject instances that have an incorrect internal state. That is,
'theA' would have pointers to the internals of 'theB', etc.

This is but one example of why you can't necessarily swap two objects
just by swapping the memory that represents them.
 
N

Nindi

Nindi said:
I have just been looking again athttp://www.gotw.ca/gotw/059.htm
What is wrong with a solution like :
class MyClass {
public:

MyClass(const MyClass
&theOther):theA(theOther.theA),theB(theOther.theB){...}
MyClass& operator=(const MyClass &theOther)
{
MyClass temp(theOther);
swap( (void *)(&theA),(void *)(&temp.theA),sizeof(InnerObject));
swap( (void *)(&theB),(void *)(&temp.theB),sizeof(InnerObject));
return *this;
}
static void swap(void *b,void *a,int count)
{
char temp;
for(int i(0);i<count;++i){
temp=((char*)(a));
((char *)(a)) = ((char *)(b));
((char *)(b))=temp;
}

InnerObject theA;
InnerObject theB;
};

to part 3 ?

Let's say InnerObject looks something like:
class InnerObject
{
private:
unsigned char data[1024] ;
unsigned char * block1 ;
unsigned char * block2 ;
public:
// Various members ...

} ;

Assume at any given time, 'block1' and 'block2' point to some location
within 'data'. Swapping in the manner you propose would now create
InnerObject instances that have an incorrect internal state. That is,
'theA' would have pointers to the internals of 'theB', etc.

This is but one example of why you can't necessarily swap two objects
just by swapping the memory that represents them.


Ok I agree, but you would write a swap function suitable for the class
at hand.
In this case you could set
block1 = &data[0] + ( theOther.block1 -
&theOther.data[0]);
The solution provided on the gotw site requires a heap allocation and
in lots of cases this will be inefficient will it not ?
So as long as you divise a swap function suitable for your particular
class would this not be 'acceptable' ?
 
J

James Kanze

[...]
The solution provided on the gotw site requires a heap allocation and
in lots of cases this will be inefficient will it not ?

In most cases, the extra overhead will not even be measurable.
If the program is too slow, and the profiler shows that it is
because of these allocations, then it's time to change. Which
you can normally do fairly simply, because the details are all
hidden within the class.
So as long as you divise a swap function suitable for your
particular class would this not be 'acceptable' ?

That's more or less the point of the GotW. Ideally, every class
would have an appropriate swap function, and you'd use it. (All
of the standard containers have such a swap function, for
example.) Tom Cargill's challenge involved using existing
types, which you couldn't change.
 

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
474,294
Messages
2,571,511
Members
48,216
Latest member
DarrelLho

Latest Threads

Top