Properties and Copy Constructors

Sergey Gromov snake.scaly at gmail.com
Thu Aug 6 15:56:53 PDT 2009


Thu, 06 Aug 2009 18:08:00 -0400, Chad J wrote:

> [snip]
> 
> The jist is that you have some value type like a Matrix or BigInt that
> might actually have memory allocated to it.  It is a value type though,
> so whenever it is copied, any memory allocated to it needs to also be
> copied and new memory allocated for the copy.
> 
> [snip]
> 
> Onwards!:
> 
> I really like Steven's suggestion, though it seems difficult to actually
> /do/.  Thus I feel this deserves to be broken down a bit more so that we
> can have our cake and eat it too.
> 
> I see two ways out of this dilemma:
> 1.  The property proxies these memory-conserving transactions.
> 2.  The getter doesn't /necessarily/ return a copy.  The setter also
> doesn't /necessarily/ create it's own copy.
> 
> Going down road (1) is tricky.  If we don't make this supremely easy to
> automate, then this will become a tedious C++-ism where any property
> ever that accesses a Matrix will have to implement the same biolerplate
> acquire/release over and over and over.  Yuck.  Even if the common cases
> are allowed to fall back to get/set, this is still yuck.  Still, there
> may be some way to automate this.  I'm just not clear what it is.
> 
> Option (2) is what I'm currently biased towards.  It also comes with
> caveats though:  if you choose to return a reference to the matrix, then
> without any guarantee that your reference is singular you will smack
> right into the aliasing problem.  Nonetheless, my cursory look at
> ref-returns seems to suggest they have this property of being singular
> in most cases.  Then we can have something like the following:
> 
> class Blah
> {
> 	property foo
> 	{
> 		ref BigInt get() { ... }
> 		ref BigInt set(ref BigInt m) { ... }
> 	}
> 
> 	// etc
> }
> 
> struct BigInt
> {
> 	void swap( ref BigInt other )
> 	{
> 		// BigInt defines it's own swap internally.
> 	}
> 
> 	// etc
> }
> 
> void main()
> {
> 	auto b1 = new Blah();
> 	auto b2 = new Blah();
> 	// Do things with b1 and b2.
> 
> 	// Now we want to swap big integers for whatever reason.
> 	b1.foo.swap(b2.foo);
> }
> 
> Now I'm assuming the ref return and ref passing of these BigInts doesn't
> invoke their copy-constructors.  Is there any reason this can't work?

Wouldn't it be better if BigInt implemented share-on-copy, copy-on-write
semantics?  This really boils down to a single reference counter within
BigInt's allocated data and working struct constructors/destructors.



More information about the Digitalmars-d mailing list