www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Pointer to a class member

reply negerns <negerns2000 gmail.com> writes:
I really do not know how to ask this question, so here's some code:

class A {
   char[] _name;
   public this(char[] n) { _name = n; }
   public char[] get() { return _name; }
}

void main() {
   auto a = new A("digitalmars");

   // I wanted a variable here to point to A._name's value
   // and manipulate it and expect the A._name's value to
   // reflect that change. Something like:

   char[] p = a.get();
   p ~= ".com";

   // and excpect a._name's value becomes "digitalmars.com"

}


-- 
negerns
Aug 20 2007
parent reply 0ffh <spam frankhirsch.net> writes:
like so?

module test;

import std.stdio;

class A {
   char[] _name;
   public this(char[] n) { _name = n; }
   public char[]* get() { return (&_name); }
   public void show() { writefln(_name); }
}

void main() {
   auto a = new A("digitalmars");

   // I wanted a variable here to point to A._name's value
   // and manipulate it and expect the A._name's value to
   // reflect that change. Something like:
   char[]* p = a.get();
   *p ~= ".com";

   // and excpect a._name's value becomes "digitalmars.com"
   a.show();
}
Aug 20 2007
parent reply negerns <negerns2000 gmail.com> writes:
0ffh wrote:

 
 module test;
 
 import std.stdio;
 
 class A {
   char[] _name;
   public this(char[] n) { _name = n; }
   public char[]* get() { return (&_name); }
   public void show() { writefln(_name); }
 }
 
 void main() {
   auto a = new A("digitalmars");
 
   // I wanted a variable here to point to A._name's value
   // and manipulate it and expect the A._name's value to
   // reflect that change. Something like:
   char[]* p = a.get();
   *p ~= ".com";
 
   // and excpect a._name's value becomes "digitalmars.com"
   a.show();
 }

How do I display the value of a._name using the variable *p? -- negerns
Aug 20 2007
parent reply negerns <negerns2000 gmail.com> writes:
negerns wrote:
 0ffh wrote:
 
 module test;

 import std.stdio;

 class A {
   char[] _name;
   public this(char[] n) { _name = n; }
   public char[]* get() { return (&_name); }
   public void show() { writefln(_name); }
 }

 void main() {
   auto a = new A("digitalmars");

   // I wanted a variable here to point to A._name's value
   // and manipulate it and expect the A._name's value to
   // reflect that change. Something like:
   char[]* p = a.get();
   *p ~= ".com";

   // and excpect a._name's value becomes "digitalmars.com"
   a.show();
 }

How do I display the value of a._name using the variable *p?

Please tell me if the following code is doing something illegal or is not a good way to do it. writefln(cast(char[])*b); -- negerns
Aug 20 2007
parent reply Lutger <lutger.blijdestijn gmail.com> writes:
negerns wrote:
 Please tell me if the following code is doing something illegal or is 
 not a good way to do it.
 
   writefln(cast(char[])*b);
 

This is correct, but not a good way to do it. The type of b is a pointer to char[], so writefln(*b) will also work. Casts are there to work around the type system but it's better to use them only if they are needed. But in this situation it may be better to not use pointers at all? I don't know how you class design looks like, so ignore this if it isn't relevant, but generally a typical getter/setter (a.k.a property) can be used like this: class A { this(char[] n) { _name = n; } char[] name() { return _name; } void name(char[] n) { _name = n; } private char[] _name; } auto a = new A("digitalmars"); char[] p = a.name; a.name = p ~ ".com"; // you cannot say a.name~=com, this is a limitation of D's properties. Or if all the data manipulation happens outside the class it may indicate that variable should be moved elsewhere.
Aug 20 2007
parent reply negerns <negerns2000 gmail.com> writes:
Lutger wrote:
 negerns wrote:
 Please tell me if the following code is doing something illegal or is 
 not a good way to do it.

   writefln(cast(char[])*b);

This is correct, but not a good way to do it. The type of b is a pointer to char[], so writefln(*b) will also work. Casts are there to work around the type system but it's better to use them only if they are needed.

Thanks, I tried the writefln(*b).
 But in this situation it may be better to not use pointers at all? I 
 don't know how you class design looks like, so ignore this if it isn't 
 relevant, but generally a typical getter/setter (a.k.a property) can be 
 used like this:
 
 class A {
     this(char[] n) { _name = n; }
     char[] name() { return _name; }
     void name(char[] n) { _name = n; }
     private char[] _name;
 }
 
 auto a = new A("digitalmars");
 char[] p = a.name;
 a.name = p ~ ".com"; // you cannot say a.name~=com, this is a limitation 
 of D's properties.
 
 Or if all the data manipulation happens outside the class it may 
 indicate that variable should be moved elsewhere.

I have a Buffer class which contain the data that i will be manipulating. class Buffer { char[] _contents; uint[] _linelength; uint[] _linestart; } The Buffer class is a member of File class which do file operations. class FileBuffer { char[] _filename; Buffer _buffer; // File operations public bool open() { ... } public bool read() { ... } public bool save() { ... } ... } There's another class that do some analysis and manipulations on the data that is in the Buffer class. I need to pass the data from the FileBuffer class without doing a copy operation since the data might be quite big and I do not want to duplicate the data, do some things and put it back in. Also, I do not think putting the buffer analysis and manipulation inside the Buffer class is good since not all Buffer objects do the analysis and manipulation routines and making that class a superclass of FileBuffer is, I believe, does not follow good OO design. class BufferAnalysis() { ... } What I am thinking right now is something like this: FileBuffer(Buffer* buffer) BufferAnalysis(Buffer* buffer) Let other classes that use the Buffer class have a pointer to the Buffer to be used and let those classes do what they want with the Buffer data without making a copy of the data but propagating any changes. Is this description of what I'm trying to do enough? :P
Aug 20 2007
parent Mike Parker <aldacron71 yahoo.com> writes:
negerns wrote:
 Lutger wrote:
 negerns wrote:
 Please tell me if the following code is doing something illegal or is 
 not a good way to do it.

   writefln(cast(char[])*b);

This is correct, but not a good way to do it. The type of b is a pointer to char[], so writefln(*b) will also work. Casts are there to work around the type system but it's better to use them only if they are needed.

Thanks, I tried the writefln(*b).
 But in this situation it may be better to not use pointers at all? I 
 don't know how you class design looks like, so ignore this if it isn't 
 relevant, but generally a typical getter/setter (a.k.a property) can 
 be used like this:

 class A {
     this(char[] n) { _name = n; }
     char[] name() { return _name; }
     void name(char[] n) { _name = n; }
     private char[] _name;
 }

 auto a = new A("digitalmars");
 char[] p = a.name;
 a.name = p ~ ".com"; // you cannot say a.name~=com, this is a 
 limitation of D's properties.

 Or if all the data manipulation happens outside the class it may 
 indicate that variable should be moved elsewhere.

I have a Buffer class which contain the data that i will be manipulating. class Buffer { char[] _contents; uint[] _linelength; uint[] _linestart; } The Buffer class is a member of File class which do file operations. class FileBuffer { char[] _filename; Buffer _buffer; // File operations public bool open() { ... } public bool read() { ... } public bool save() { ... } ... } There's another class that do some analysis and manipulations on the data that is in the Buffer class. I need to pass the data from the FileBuffer class without doing a copy operation since the data might be quite big and I do not want to duplicate the data, do some things and put it back in. Also, I do not think putting the buffer analysis and manipulation inside the Buffer class is good since not all Buffer objects do the analysis and manipulation routines and making that class a superclass of FileBuffer is, I believe, does not follow good OO design. class BufferAnalysis() { ... } What I am thinking right now is something like this: FileBuffer(Buffer* buffer) BufferAnalysis(Buffer* buffer) Let other classes that use the Buffer class have a pointer to the Buffer to be used and let those classes do what they want with the Buffer data without making a copy of the data but propagating any changes. Is this description of what I'm trying to do enough? :P

You don't need pointers for this. Unlike in C++, classes in D are automatically references. Thus this should do what you want: FileBuffer(Buffer buffer); BufferAnalysis(Buffer buffer); Structs are different and are passed by value, meaning they are copied. So when using structs to achieve the same result, you should use the ref keyword: struct MyStruct { ubyte[] contents; } SomeFunc(ref MyStruct ms); But actually, arrays in D are just an object with two fields -- a size and a pointer. So even when passing MyStruct by value, you aren't copying the data that contents points do, just the size and pointer (8 bytes on a 32-bit system). Also, you might consider using byte or ubyte for the type of your contents array, rather than char.
Aug 21 2007