www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Constructors (starstruck noob from C++)

reply "Luke J. West" <luke west.me.uk> writes:
Hi to all from a total noob.

first of all, I'd like to say how impressed I am with D. In fact, I keep
pinching myself. Have I *really* found a language worth leaving C++ for
after two decades? It's beginning to look that way. Obviously I'm
devouring the 2.0 documentation right now, but have not yet found out
how to create a new instance of an existing class object. What I mean
is, given...

auto a = new A;

how do I, in c++ speak, do the D for...

A  b(a); // or if you prefer...
A* b = new A(a);

I'm sure this must be trivial.

Many many thanks,

Luke
Jan 20 2011
next sibling parent Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
Welcome!

On 01/20/2011 07:18 PM, Luke J. West wrote:
 how do I, in c++ speak, do the D for...

 A  b(a); // or if you prefer...
 A* b = new A(a);

try A b = new A(a);
 I'm sure this must be trivial.

 Many many thanks,

 Luke

Jan 20 2011
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/20/11 7:18 PM, Luke J. West wrote:
 Hi to all from a total noob.

 first of all, I'd like to say how impressed I am with D. In fact, I keep
 pinching myself. Have I *really* found a language worth leaving C++ for
 after two decades? It's beginning to look that way. Obviously I'm
 devouring the 2.0 documentation right now, but have not yet found out
 how to create a new instance of an existing class object. What I mean
 is, given...

 auto a = new A;

 how do I, in c++ speak, do the D for...

 A  b(a); // or if you prefer...
 A* b = new A(a);

 I'm sure this must be trivial.

 Many many thanks,

 Luke

Hopefully this won't mark a demise of your newfound interest :o). If A were a struct, auto b = new A(*a) would do. For classes, D does not provide automatic copy constructors; you need to define and follow a sort of cloning protocol. That being said, it's not difficult to define a generic function that copies fields over from one class object to another. Here's a start: import std.stdio; void copyMembers(A)(A src, A tgt) if (is(A == class)) { foreach (e; __traits(allMembers, A)) { static if (!is(typeof(__traits(getMember, src, e)) == function) && e != "Monitor") { __traits(getMember, tgt, e) = __traits(getMember, src, e); } } } class A { int x = 42; string y = "hello"; final void fun1() {} void fun2() {} static void fun3(){} } void main() { auto a = new A; a.x = 43; auto b = new A; copyMembers(a, b); assert(b.x == 43); } I think copyMembers belongs to the standard library. I wanted to define a family of functions like it but never got around to it. Andrei
Jan 20 2011
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-01-21 04:02, Andrei Alexandrescu wrote:
 On 1/20/11 7:18 PM, Luke J. West wrote:
 Hi to all from a total noob.

 first of all, I'd like to say how impressed I am with D. In fact, I keep
 pinching myself. Have I *really* found a language worth leaving C++ for
 after two decades? It's beginning to look that way. Obviously I'm
 devouring the 2.0 documentation right now, but have not yet found out
 how to create a new instance of an existing class object. What I mean
 is, given...

 auto a = new A;

 how do I, in c++ speak, do the D for...

 A b(a); // or if you prefer...
 A* b = new A(a);

 I'm sure this must be trivial.

 Many many thanks,

 Luke

Hopefully this won't mark a demise of your newfound interest :o). If A were a struct, auto b = new A(*a) would do. For classes, D does not provide automatic copy constructors; you need to define and follow a sort of cloning protocol. That being said, it's not difficult to define a generic function that copies fields over from one class object to another. Here's a start: import std.stdio; void copyMembers(A)(A src, A tgt) if (is(A == class)) { foreach (e; __traits(allMembers, A)) { static if (!is(typeof(__traits(getMember, src, e)) == function) && e != "Monitor") { __traits(getMember, tgt, e) = __traits(getMember, src, e); } } } class A { int x = 42; string y = "hello"; final void fun1() {} void fun2() {} static void fun3(){} } void main() { auto a = new A; a.x = 43; auto b = new A; copyMembers(a, b); assert(b.x == 43); } I think copyMembers belongs to the standard library. I wanted to define a family of functions like it but never got around to it. Andrei

Or you can use a serialization library, serialize the struct, then deserialize it and you have a deep copy. For example using Orange: http://dsource.org/projects/orange/ . Although it would not be very efficient to use XML as an intermediate format. -- /Jacob Carlborg
Jan 21 2011
prev sibling next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/20/11 11:28 PM, Robert Jacques wrote:
 On Thu, 20 Jan 2011 22:02:42 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 First, why not use tupleof? b.tupleof = a.tupleof; works perfectly fine,
 simpler and ahem, actually works. __traits(getMember, ...) has to obey
 scoping rules, so using it with a class that defines private variables
 results in a message like class hello.A member x is not accessible.
 Furthermore, you need to filter allMembers by a lot more than just
 function and "Monitor" as it also includes enum constants, etc. Having
 tried using it for serialization, I know it's non-trivial to use
 correctly, if you only want the actual data fields.

 i.e.

 void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
 src.tupleof; }

Indeed, that's the canonical solution. Thanks for the reminder. Andrei
Jan 21 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On 01/21/2011 04:48 AM, Andrej Mitrovic wrote:
 On 1/21/11, Andrei Alexandrescu<SeeWebsiteForEmail erdani.org>  wrote:
 I think copyMembers belongs to the standard library. I wanted to define
 a family of functions like it but never got around to it.

It's a shame we can't use .dup. It would look really nice in code.

+++ Denis _________________ vita es estrany spir.wikidot.com
Jan 21 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
spir:

 It's a shame we can't use .dup. It would look really nice in code.

+++

Copying classes is not a so common need in D. As an example, I need a byPair() method for AAs more than dup for classes :-) Bye, bearophile
Jan 21 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 01/21/2011 01:29 PM, bearophile wrote:
 spir:

 It's a shame we can't use .dup. It would look really nice in code.

+++

Copying classes is not a so common need in D. As an example, I need a

 Bye,
 bearophile

Sure, but when you need it, you very pleased to find it. And as already noted, this thread shows how non-obviously it is to define. By the way, I like & support you request for byPair; but then, let's have it for all arrays (keys beeing indices). (D Lua-isation ;-) Denis _________________ vita es estrany spir.wikidot.com
Jan 21 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
spir:

 How many programmers in the world consider this kind of code "not 
 difficult"?

(True complex code is when you have to maintain or improve ocean-wide programs :-) ) That kind of code is library-level one, so it's more difficult than normal user code. Bye, bearophile
Jan 21 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 01/21/2011 06:28 AM, Robert Jacques wrote:
 void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
 src.tupleof; }

What about this feature in Object under name "copy" or "dup"? Sure, it's not to be used evereday; but it's typcally the kind of routine that, when needed, we're very happy to find. And as shown by this thread the solution is clearly non-obvious (lol). By the way, why "dup" in D, instead of most common "copy" or "clone"? Is it also a legacy name? (Don't tell me we got this one from stack-based languages like Forth ;-) Anyway the semantics are totally different (*)). Denis (*) for very curious people: concatenative languages: http://concatenative.org/wiki/view/Concatenative%20language _________________ vita es estrany spir.wikidot.com
Jan 21 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 01/21/2011 05:27 PM, Robert Jacques wrote:
 On Fri, 21 Jan 2011 08:16:24 -0500, spir <denis.spir gmail.com> wrote:

 On 01/21/2011 06:28 AM, Robert Jacques wrote:
 void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
 src.tupleof; }

What about this feature in Object under name "copy" or "dup"? Sure, it's not to be used evereday; but it's typcally the kind of routine that, when needed, we're very happy to find. And as shown by this thread the solution is clearly non-obvious (lol). By the way, why "dup" in D, instead of most common "copy" or "clone"? Is it also a legacy name? (Don't tell me we got this one from stack-based languages like Forth ;-) Anyway the semantics are totally different (*)). Denis (*) for very curious people: concatenative languages: http://concatenative.org/wiki/view/Concatenative%20language _________________ vita es estrany spir.wikidot.com

".dup" comes from arrays, which already have a ".dup" property which copies/clones them.

Yes. I was in fact (unclearly) wondering where .dup for arrays comes from. I mean, the obvious term --and short enough to not even look for an abbreviation possibly making it obscure-- is "copy", isn't it? (*) Denis _________________ vita es estrany spir.wikidot.com (*) Or do people really speak like: << Would you please make a duplicate of the guest list? >> in the US?
Jan 21 2011
prev sibling parent Pelle <pelle.mansson gmail.com> writes:
On 01/21/2011 02:02 PM, spir wrote:
 On 01/21/2011 04:02 AM, Andrei Alexandrescu wrote:
 That being said, it's not difficult to define a generic function that
 copies fields over from one class object to another. Here's a start:

 import std.stdio;

 void copyMembers(A)(A src, A tgt) if (is(A == class)) {
 foreach (e; __traits(allMembers, A)) {
 static if (!is(typeof(__traits(getMember, src, e)) == function)
 && e != "Monitor")
 {
 __traits(getMember, tgt, e) = __traits(getMember, src, e);
 }
 }
 }

<side-note> How many programmers in the world consider this kind of code "not difficult"? These few lines mix 3 features I personly find, say, 'special': generics using 'is' constraints, static if, __traits. <personal> From those 3, static if is not ugly. </personal> Is code like this supposed to be considered normal? Where is D2 speak going to? Merge into this a handful of range/algos, a pinch of happy qualifiers here & there, a specimen of... string-mixin ;-) How to welcome newcomers? </side-note> Denis _________________ vita es estrany spir.wikidot.com

What you're saying doesn't make sense. :-) You welcome them by saying they can copy a class object by using copyMembers. Newcomers may not write that code, but using it is dead simple. I suspect most D users couldn't implement floating point formatting either, or a bunch of other hard stuff.
Jan 22 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/21/11, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:
 I think copyMembers belongs to the standard library. I wanted to define
 a family of functions like it but never got around to it.

It's a shame we can't use .dup. It would look really nice in code.
Jan 20 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Thu, 20 Jan 2011 22:02:42 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 On 1/20/11 7:18 PM, Luke J. West wrote:
 Hi to all from a total noob.

 first of all, I'd like to say how impressed I am with D. In fact, I keep
 pinching myself. Have I *really* found a language worth leaving C++ for
 after two decades? It's beginning to look that way. Obviously I'm
 devouring the 2.0 documentation right now, but have not yet found out
 how to create a new instance of an existing class object. What I mean
 is, given...

 auto a = new A;

 how do I, in c++ speak, do the D for...

 A  b(a); // or if you prefer...
 A* b = new A(a);

 I'm sure this must be trivial.

 Many many thanks,

 Luke

Hopefully this won't mark a demise of your newfound interest :o). If A were a struct, auto b = new A(*a) would do. For classes, D does not provide automatic copy constructors; you need to define and follow a sort of cloning protocol. That being said, it's not difficult to define a generic function that copies fields over from one class object to another. Here's a start: import std.stdio; void copyMembers(A)(A src, A tgt) if (is(A == class)) { foreach (e; __traits(allMembers, A)) { static if (!is(typeof(__traits(getMember, src, e)) == function) && e != "Monitor") { __traits(getMember, tgt, e) = __traits(getMember, src, e); } } } class A { int x = 42; string y = "hello"; final void fun1() {} void fun2() {} static void fun3(){} } void main() { auto a = new A; a.x = 43; auto b = new A; copyMembers(a, b); assert(b.x == 43); } I think copyMembers belongs to the standard library. I wanted to define a family of functions like it but never got around to it. Andrei

First, why not use tupleof? b.tupleof = a.tupleof; works perfectly fine, simpler and ahem, actually works. __traits(getMember, ...) has to obey scoping rules, so using it with a class that defines private variables results in a message like class hello.A member x is not accessible. Furthermore, you need to filter allMembers by a lot more than just function and "Monitor" as it also includes enum constants, etc. Having tried using it for serialization, I know it's non-trivial to use correctly, if you only want the actual data fields. i.e. void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof = src.tupleof; }
Jan 20 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 01/21/2011 04:02 AM, Andrei Alexandrescu wrote:
 That being said, it's not difficult to define a generic function that
 copies fields over from one class object to another. Here's a start:

 import std.stdio;

 void copyMembers(A)(A src, A tgt) if (is(A == class)) {
      foreach (e; __traits(allMembers, A)) {
          static if (!is(typeof(__traits(getMember, src, e)) == function)
 && e != "Monitor")
          {
              __traits(getMember, tgt, e) = __traits(getMember, src, e);
          }
      }
 }

<side-note> How many programmers in the world consider this kind of code "not difficult"? These few lines mix 3 features I personly find, say, 'special': generics using 'is' constraints, static if, __traits. <personal> From those 3, static if is not ugly. </personal> Is code like this supposed to be considered normal? Where is D2 speak going to? Merge into this a handful of range/algos, a pinch of happy qualifiers here & there, a specimen of... string-mixin ;-) How to welcome newcomers? </side-note> Denis _________________ vita es estrany spir.wikidot.com
Jan 21 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Theorizing: Would it be a bad idea if .dup for classes did the same
thing as normal assignment did for structs with postblit constructors?

Essentially I was thinking that code like this would do the trick:

import std.stdio;

class Widget
{
    int integral;  // field-by-field assignment
    int[] array;   // this needs a postblit
    this(uint length)
    {
        array = new int[length];
    }

    this(this)
    {
        array = array.dup;
    }
}

void main()
{
    auto w1 = new Widget(10);
    auto w2 = w1.dup;
    assert(w1.array !is w2.array);
}

I like uniformity in a language, it's much easier to get the rules
right this way. But I'm speculating whether this would even work
right..
Jan 21 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Fri, 21 Jan 2011 08:16:24 -0500, spir <denis.spir gmail.com> wrote:

 On 01/21/2011 06:28 AM, Robert Jacques wrote:
 void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
 src.tupleof; }

What about this feature in Object under name "copy" or "dup"? Sure, it's not to be used evereday; but it's typcally the kind of routine that, when needed, we're very happy to find. And as shown by this thread the solution is clearly non-obvious (lol). By the way, why "dup" in D, instead of most common "copy" or "clone"? Is it also a legacy name? (Don't tell me we got this one from stack-based languages like Forth ;-) Anyway the semantics are totally different (*)). Denis (*) for very curious people: concatenative languages: http://concatenative.org/wiki/view/Concatenative%20language _________________ vita es estrany spir.wikidot.com

".dup" comes from arrays, which already have a ".dup" property which copies/clones them.
Jan 21 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 21 Jan 2011 14:54:53 -0500, spir <denis.spir gmail.com> wrote:

 On 01/21/2011 05:27 PM, Robert Jacques wrote:
 On Fri, 21 Jan 2011 08:16:24 -0500, spir <denis.spir gmail.com> wrote:

 On 01/21/2011 06:28 AM, Robert Jacques wrote:
 void copyMembers(A)(A src, A tgt) if (is(A == class)) { tgt.tupleof =
 src.tupleof; }

What about this feature in Object under name "copy" or "dup"? Sure, it's not to be used evereday; but it's typcally the kind of routine that, when needed, we're very happy to find. And as shown by this thread the solution is clearly non-obvious (lol). By the way, why "dup" in D, instead of most common "copy" or "clone"? Is it also a legacy name? (Don't tell me we got this one from stack-based languages like Forth ;-) Anyway the semantics are totally different (*)). Denis (*) for very curious people: concatenative languages: http://concatenative.org/wiki/view/Concatenative%20language _________________ vita es estrany spir.wikidot.com

".dup" comes from arrays, which already have a ".dup" property which copies/clones them.

Yes. I was in fact (unclearly) wondering where .dup for arrays comes from. I mean, the obvious term --and short enough to not even look for an abbreviation possibly making it obscure-- is "copy", isn't it? (*)

Not sure where it comes from, but dup also is a system call in Linux: dup, dup2, dup3 - duplicate a file descriptor The terminology isn't really important as long as its relevant. Perhaps dup was chosen to avoid confusion with STL's std::copy (which copies data into an already-allocated area)? The difference is subtle. In any case, dup is clearly here to stay as the way to copy arrays, I'd agree that it makes sense to re-use it as the way to duplicate objects as well. I use it in dcollections.
 (*)
 Or do people really speak like:
 << Would you please make a duplicate of the guest list? >>
 in the US?

They might, it doesn't sound that odd to me, though copy sounds more common. -Steve
Jan 21 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 21, 2011 12:10:26 Steven Schveighoffer wrote:
 On Fri, 21 Jan 2011 14:54:53 -0500, spir <denis.spir gmail.com> wrote:
 (*)
 Or do people really speak like:
 << Would you please make a duplicate of the guest list? >>
 in the US?

They might, it doesn't sound that odd to me, though copy sounds more common.

I'd find that a bit odd, personally. It's perfectly understandable but a bit odd. I think that part of the problem though is that you're talking about a document, and you don't typically talk about duplicating documents. Actually, if you want to get really technical, I think that duplicate is most typically used when talking about someone doing the same thing as someone else rather than taking the original and copying it. So, instead of taking the guest list and copying it, if you're duplicating it, then that often would imply that you're recreating it yourself rather than copying the one that exists - though, it is a bit odd to talk that way about a document. More typically, you'd talk about a technological device or whatnot. It's like how you'd say that you duplicated effort, but you'd never say that you copied effort. That's not to say that the use of either copy or duplicate is entirely consistent however. Language is a rather maleable thing, and common usage has a large effect, regardless of what is technically correct based on the definitions of the words. - Jonathan M Davis
Jan 21 2011