www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How to new a class object in a struct

reply zhang <bitworld qq.com> writes:
Here are some codes:

class AClass
{
    int a = 10;
}

struct AStruct
{
    AClass aclass;

//    this()  // can't do this in a struct
//    {
//        aclass = new AClass()
//    }

    this(AClass aclass_)
    {
        aclass = aclass_;
    }
}


int main(string[] args)
{
    AStruct astruct;
    int a = astruct.aclass.a;
    writefln("%d", a);
    return 0;
}


In D, this() is prohibited in a struct. So
   AStruct astruct
will leave the aclass object to be null. It's not like the way in C++, the
aclass object will be created automatically.

It always leads some problems when doing porting from C++ to D.

My solution is to use class instead of struct. Then I can create the aclass
object in this() when I new an AStruct.

Any suggestion? 
Thanks.

----------
Zhang <bitworld qq.com>
Sep 01 2011
next sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/01/2011 04:10 PM, zhang wrote:
 Here are some codes:

 class AClass
 {
      int a = 10;
 }

 struct AStruct
 {
      AClass aclass;

 //    this()  // can't do this in a struct
 //    {
 //        aclass = new AClass()
 //    }

      this(AClass aclass_)
      {
          aclass = aclass_;
      }
 }


 int main(string[] args)
 {
      AStruct astruct;
      int a = astruct.aclass.a;
      writefln("%d", a);
      return 0;
 }


 In D, this() is prohibited in a struct. So
     AStruct astruct
 will leave the aclass object to be null. It's not like the way in C++, the
aclass object will be created automatically.

 It always leads some problems when doing porting from C++ to D.

 My solution is to use class instead of struct. Then I can create the aclass
object in this() when I new an AStruct.

 Any suggestion?
 Thanks.

 ----------
 Zhang<bitworld qq.com>

This works: class AClass { int a = 10; } struct AStruct { AClass aclass; // this() disable; // will be in the next DMD release static AStruct opCall() { return AStruct(new AClass()); } static AStruct opCall(AClass aclass_) { AStruct result = void; result.aclass = aclass_; return result; } } int main(string[] args) { auto astruct = AStruct(); int a = astruct.aclass.a; writefln("%d", a); return 0; }
Sep 01 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
You could do something like this:

class AClass
{
   int a = 10;
}

struct AStruct
{
   // Never use this directly, except inside the "aclass" property functions
   private AClass _aclass;

     property AClass aclass()
    {
        if(_aclass is null)
            _aclass = new AClass();
        return _aclass;
    }

     property void aclass(AClass c)
    {
        _aclass = c;
    }
}

-------------------------------
Not sent from an iPhone.
Sep 01 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message 
news:op.v046zvlfeav7ka localhost.localdomain...
 On Thu, 01 Sep 2011 13:31:29 -0400, Nick Sabalausky <a a.a> wrote:

 You could do something like this:

 class AClass
 {
    int a = 10;
 }

 struct AStruct
 {
    // Never use this directly, except inside the "aclass" property 
 functions
    private AClass _aclass;

      property AClass aclass()
     {
         if(_aclass is null)
             _aclass = new AClass();
         return _aclass;
     }

      property void aclass(AClass c)
     {
         _aclass = c;
     }
 }

 -------------------------------
 Not sent from an iPhone.

This doesn't work. It has the same problem as AA's currently do: foo(AStruct str) { str.aclass.a = 5; } void main() { AStruct str; // assert(str.aclass.a == 10); foo(str); assert(str.aclass.a == 5); // fails unless you comment out the line above. }

Could using postblit solve that (or am I misunderstanding the issue)?
Sep 01 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 09/01/2011 10:35 PM, Nick Sabalausky wrote:
 "Steven Schveighoffer"<schveiguy yahoo.com>  wrote in message
 news:op.v046zvlfeav7ka localhost.localdomain...
 On Thu, 01 Sep 2011 13:31:29 -0400, Nick Sabalausky<a a.a>  wrote:

 You could do something like this:

 class AClass
 {
     int a = 10;
 }

 struct AStruct
 {
     // Never use this directly, except inside the "aclass" property
 functions
     private AClass _aclass;

       property AClass aclass()
      {
          if(_aclass is null)
              _aclass = new AClass();
          return _aclass;
      }

       property void aclass(AClass c)
      {
          _aclass = c;
      }
 }

 -------------------------------
 Not sent from an iPhone.

This doesn't work. It has the same problem as AA's currently do: foo(AStruct str) { str.aclass.a = 5; } void main() { AStruct str; // assert(str.aclass.a == 10); foo(str); assert(str.aclass.a == 5); // fails unless you comment out the line above. }

Could using postblit solve that (or am I misunderstanding the issue)?

Postblit has no access to the original struct, so how would you solve the issue using postblit?
Sep 01 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 01 Sep 2011 13:31:29 -0400, Nick Sabalausky <a a.a> wrote:

 You could do something like this:

 class AClass
 {
    int a = 10;
 }

 struct AStruct
 {
    // Never use this directly, except inside the "aclass" property  
 functions
    private AClass _aclass;

      property AClass aclass()
     {
         if(_aclass is null)
             _aclass = new AClass();
         return _aclass;
     }

      property void aclass(AClass c)
     {
         _aclass = c;
     }
 }

 -------------------------------
 Not sent from an iPhone.

This doesn't work. It has the same problem as AA's currently do: foo(AStruct str) { str.aclass.a = 5; } void main() { AStruct str; // assert(str.aclass.a == 10); foo(str); assert(str.aclass.a == 5); // fails unless you comment out the line above. } And to answer the OP's question, the easiest thing to do is create a constructor function (not a ctor, because you can't have default ctors). Yes, it's annoying, but it's about as close as you can get to C++. struct AStruct { static AStruct create() {return AStruct(new AClass());} } auto str = AStruct.create(); Until the next release, there is no way to force a user to always call such a function. The next relase allows disable this(), which should disable simply declaring a struct. This is an alternative to Timon's opCall solution. -Steve
Sep 01 2011
prev sibling next sibling parent reply "Marco Leise" <Marco.Leise gmx.de> writes:
Am 01.09.2011, 16:10 Uhr, schrieb zhang <bitworld qq.com>:

 Here are some codes:

 class AClass
 {
     int a = 10;
 }

 struct AStruct
 {
     AClass aclass;

 //    this()  // can't do this in a struct
 //    {
 //        aclass = new AClass()
 //    }

     this(AClass aclass_)
     {
         aclass = aclass_;
     }
 }


 int main(string[] args)
 {
     AStruct astruct;
     int a = astruct.aclass.a;
     writefln("%d", a);
     return 0;
 }


 In D, this() is prohibited in a struct. So
    AStruct astruct
 will leave the aclass object to be null. It's not like the way in C++,  
 the aclass object will be created automatically.

 It always leads some problems when doing porting from C++ to D.

 My solution is to use class instead of struct. Then I can create the  
 aclass object in this() when I new an AStruct.

 Any suggestion?
 Thanks.

 ----------
 Zhang <bitworld qq.com>

C++ has an easy position because it handles structs almost like classes. The only difference I notice is that everything is public by default in a struct. So technically your structs would probably better be matched by D classes. But that's of course not what you intended in the C++ code in the first place. :)
Sep 01 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 09/01/2011 06:45 PM, Jonathan M Davis wrote:
 On Thursday, September 01, 2011 16:26 Marco Leise wrote:
 C++ has an easy position because it handles structs almost like classes.
 The only difference I notice is that everything is public by default in a
 struct.

That _is_ the only difference between structs and classes in C++. - Jonathan M Davis

Default inheritance protection is different, too. Andrei
Sep 01 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, September 01, 2011 16:26 Marco Leise wrote:
 C++ has an easy position because it handles structs almost like classes.
 The only difference I notice is that everything is public by default in a
 struct.

That _is_ the only difference between structs and classes in C++. - Jonathan M Davis
Sep 01 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, September 01, 2011 20:33:05 Andrei Alexandrescu wrote:
 On 09/01/2011 06:45 PM, Jonathan M Davis wrote:
 On Thursday, September 01, 2011 16:26 Marco Leise wrote:
 C++ has an easy position because it handles structs almost like
 classes.
 The only difference I notice is that everything is public by default
 in a struct.

That _is_ the only difference between structs and classes in C++. - Jonathan M Davis

Default inheritance protection is different, too.

Well, that would arguably be part of "everything is public by default," but it's a good point. - Jonathan M Davis
Sep 01 2011
prev sibling parent Mehrdad <wfunction hotmail.com> writes:
On 9/1/2011 7:10 AM, zhang wrote:
 It's not like the way in C++, the aclass object will be created automatically.

Yes, because D classes are NOT equal to C++ classes. D classes are reference types, and C++ "classes" are structs. So D classes *pointers* to C++ classes, which are obviously NULL by default.
Sep 01 2011