tags:

views:

63

answers:

3

So I've got an output stream class that owns a pointer to a class that actually does the writing, and I need a copy constructor so that I can return initialized instances from a function so that I can bind certain values transparently to the user. To have reasonable copy semantics I'd really like to clear the writer pointer in the copied object and close it rendering it unusable during copy.

I can do that just fine with a non-const copy constructor, a-la:

class Test {
  public:
    Test(Test& other);
};

But I want to be able to assign directly from the temporary returned by a function call:

Test test = make_test();

The copy constructor is required to be const. So I'm curious of what the implications of using a const_cast in the copy constructor would be. I'd cast the other reference to a non-const pointer and clear the writer pointer I mentioned. I know const_cast is generally considered evil but could it work in this case? I'm especially curious how it will interact with temporary objects returned from a function call.

Alternatively there's only like four creation functions that I really want to have access to the copy constructor, if there was a reasonable way to scope it so that it was only usable to those functions (including their return values) then I'd prefer that.

+2  A: 

You would be violating the public contract of your object and the expectations of any client code by making your const copy constructor destructive.

Other than that, there's no problem with removing the constness of the parameter.

Franci Penov
Ideally the user would never be able to copy these objects but circumstances require me to do otherwise. I plan on making it very clear that copying the objects invalidates the source object, and the user's notified very clearly through the exception system when they try to write through the old object. I racked my brain going around and around on how to architect this right but this one required the least compromises. Thanks for the assurance that it it's technically OK if not morally ;)
gct
+1  A: 

You might wish to take a look at std::auto_ptr's implementation as its copy constructor also mutates the original object.

But be aware that this semantic is precisely why a lot of people dislike std::auto_ptr.

jamesdlin
+3  A: 

Sounds like a job for mutable:

struct A {

    A() : x(0) {}

    A( const A & a ) : x( a.x ) {
       a.x = 0;
    }

    mutable int x;
};

int main() {
    A a1;
    A a2 = a1;
}
anon
Ooh I had no idea that even existed, that will probably work great
gct