digitalmars.D - class allocators should be more encapsulated
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (55/55) Dec 29 2006 Hello all.
- Frits van Bommel (7/34) Dec 29 2006 I don't think that's what custom allocators were designed to do. They
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (8/15) Dec 29 2006 Well, allocators do take parameters. The only reason for that has to be
- Frits van Bommel (12/30) Dec 29 2006 Yes they do take parameters, and the reason is indeed to customize how
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (9/15) Dec 29 2006 You are right. If I return an existing object it will be initialized to
- Thomas Kuehne (29/42) Dec 29 2006 Where is the problem?
- =?ISO-8859-1?Q?Lu=EDs_Marques?= (19/45) Dec 29 2006 I did not know that was possible (from my searches on google perhaps
- Bruno Medeiros (52/100) Dec 30 2006 Whoa there, 'this' assigning? I feel a disturbance in the Source. I
- Bruno Medeiros (7/27) Dec 30 2006 Why should "new ClassType()" be able to return the same instance? What's...
- Benji Smith (19/23) Dec 29 2006 Isn't this the standard idiom for this kind of keyed singleton pattern?
- BCS (25/37) Dec 29 2006 I think what would be needed is a total replacement for the creation of
Hello all. I need to build a class for which there should be only one instance with a given attribute (of type char[]). That can be provided by a class allocator with the following form: new (uint size, char[] data) { ... } The same "data" must then also be a constructor parameter: this(char[] data) { this.data = data; ... } Allocations then take the form: new("my string") ClassType("my string"); static method or in a template, but that takes away the point of a customized new: we are mostly back to the C++ method of having a private constructor and providing a factory method. new() does cannot be stored in the instance, so this() has to perform them again. In my case, the data's hash is both computed on the new() (to check for an existing instance in an associative array) and on this() (to store it). Also, overloaded forms of new() and this() taking a dchar[] both have to converted the data to UTF-8 prior to calling the respective char[] variants; Given this, I think a solution should be found to better encapsulate new(). Suggestion: - forms of "new(...) Class(...)" are deprecated - this() has to call the appropriate new() prior to accessing any of its members. Otherwise the default class allocator is called. - any arguments to new() are be passed to this() instead E.g. class Foo { private int attr z; private new(uint size, int param) { ... allocate memory according to param } this(float bla, int param) { int x = param * 3; new(x); z = bla * param; } this(float bla) { // default allocator called z = cast(int) bla / 2; } } -- Luís Marques
Dec 29 2006
Luís Marques wrote:Hello all. I need to build a class for which there should be only one instance with a given attribute (of type char[]). That can be provided by a class allocator with the following form: new (uint size, char[] data) { ... } The same "data" must then also be a constructor parameter: this(char[] data) { this.data = data; ... }I don't think that's what custom allocators were designed to do. They should only allocate some memory (and register it with the gc if necessary).Allocations then take the form: new("my string") ClassType("my string"); static method or in a template, but that takes away the point of a customized new: we are mostly back to the C++ method of having a private constructor and providing a factory method.Well, in D the factory method can be static opCall(), so allocation can look like this: ClassType("my string") which looks a lot cleaner than the normal ClassType.create("my string").
Dec 29 2006
Frits van Bommel wrote:I don't think that's what custom allocators were designed to do. They should only allocate some memory (and register it with the gc if necessary).Well, allocators do take parameters. The only reason for that has to be being able to customize how the memory is allocated, right? From what I can see in my example my example still applies (I have seen several people use new for singleton patterns). Perhaps you disagree. Would you care to elaborate?Well, in D the factory method can be static opCall(), so allocation can look like this: ClassType("my string") which looks a lot cleaner than the normal ClassType.create("my string").Well point out, thanks! But still, isn't new ClassType("my string") better?
Dec 29 2006
Luís Marques wrote:Frits van Bommel wrote:Yes they do take parameters, and the reason is indeed to customize how memory is allocated. But unless they throw an exception, they do have to actually _allocate_ some memory. If they don't throw, the return value must be a void* to a newly-allocated piece of memory. So what I gather you're trying to do (potentially return a pointer to an already-existing object) isn't acceptable behavior for a custom allocator.I don't think that's what custom allocators were designed to do. They should only allocate some memory (and register it with the gc if necessary).Well, allocators do take parameters. The only reason for that has to be being able to customize how the memory is allocated, right? From what I can see in my example my example still applies (I have seen several people use new for singleton patterns). Perhaps you disagree. Would you care to elaborate?A 'new' (that doesn't throw) is supposed to always actually creates a *new* object... Anything that conditionally creates a new object to return should really be a function/method/static opCall, not a custom allocator or constructor. It's just not what they're meant to do.Well, in D the factory method can be static opCall(), so allocation can look like this: ClassType("my string") which looks a lot cleaner than the normal ClassType.create("my string").Well point out, thanks! But still, isn't new ClassType("my string") better?
Dec 29 2006
Frits van Bommel wrote:Yes they do take parameters, and the reason is indeed to customize how memory is allocated. But unless they throw an exception, they do have to actually _allocate_ some memory. If they don't throw, the return value must be a void* to a newly-allocated piece of memory. So what I gather you're trying to do (potentially return a pointer to an already-existing object) isn't acceptable behavior for a custom allocator.You are right. If I return an existing object it will be initialized to default values. I guess that means the solution to a singleton pattern proposed by Burton Radons does not work (http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=D&artnum=14520) Still, it's a pity that "new ClassType()" cannot be used to transparently return an existing object (conditionally or not). -- Luís Marques
Dec 29 2006
Luís Marques <luismarques gmail.com> schrieb:Frits van Bommel wrote:Where is the problem? If you use this pattern alot, the GC will have to do some more cleaning. ThomasYes they do take parameters, and the reason is indeed to customize how memory is allocated. But unless they throw an exception, they do have to actually _allocate_ some memory. If they don't throw, the return value must be a void* to a newly-allocated piece of memory. So what I gather you're trying to do (potentially return a pointer to an already-existing object) isn't acceptable behavior for a custom allocator.You are right. If I return an existing object it will be initialized to default values. I guess that means the solution to a singleton pattern proposed by Burton Radons does not work (http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=D&artnum=14520) Still, it's a pity that "new ClassType()" cannot be used to transparently return an existing object (conditionally or not).
Dec 29 2006
Thomas Kuehne wrote:If you use this pattern alot, the GC will have to do some more cleaning.I did not know that was possible (from my searches on google perhaps several other people didn't too?). About the GC, might this make it better? this() { static Some existing; if(existing is null){ existing = this; }else{ delete this; this = existing; } } The only minor issue remaining is perhaps that some CPU cycles are wasted creating the unnecessary object? Thanks for this information :) -- Luís Marques
Dec 29 2006
Thomas Kuehne wrote:Luís Marques <luismarques gmail.com> schrieb:Whoa there, 'this' assigning? I feel a disturbance in the Source. I think that is not valid behavior, from an OO point of view. The spec doesn't mention anything like that (AFAIK), and from the implementation point of view, it's undefined behavior: From some small tests I've made you can only change the 'this' pointer as if it was an inout ref, if 'this()' is not called as a parent constructor (that is, as a part of the construction of a subclass). I would say this merits a bug. ---- Code: ---- import std.stdio; import stdext.stdio; class Foo { static bool first = true; this() { if(first){ first = false; writeln("IN FIRST, this= ", cast(void *)this); this = new FooBaz(); writeln("END FIRST, this= ", cast(void *)this); } } } class FooBar : Foo { int[100] iar; this() { writeln("IN FooBar(), this= ", cast(void *)this); } } class FooBaz : Foo { this() { writeln("IN FooBaz(), this= ", cast(void *)this); } } int main(char[][] args) { writeln(">>> NEW Foo:"); Foo foo = new Foo(); writeln("foo= ", cast(void *)foo); Foo.first = true; writeln(">>> NEW FooBar:"); FooBar myfoo = new FooBar(); writeln("#myfoo= ", cast(void *)myfoo); writeln("#myfoo as FooBaz ", cast(FooBaz) myfoo); writeln("#myfoo as FooBar ", cast(FooBar) myfoo); return 0; } -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DFrits van Bommel wrote:Where is the problem? If you use this pattern alot, the GC will have to do some more cleaning. ThomasYes they do take parameters, and the reason is indeed to customize how memory is allocated. But unless they throw an exception, they do have to actually _allocate_ some memory. If they don't throw, the return value must be a void* to a newly-allocated piece of memory. So what I gather you're trying to do (potentially return a pointer to an already-existing object) isn't acceptable behavior for a custom allocator.You are right. If I return an existing object it will be initialized to default values. I guess that means the solution to a singleton pattern proposed by Burton Radons does not work (http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=D&artnum=14520) Still, it's a pity that "new ClassType()" cannot be used to transparently return an existing object (conditionally or not).
Dec 30 2006
Luís Marques wrote:Frits van Bommel wrote:Why should "new ClassType()" be able to return the same instance? What's wrong with ClassType.getInstance() ? Or in your case ClassType.getInstance("my string") ? -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DYes they do take parameters, and the reason is indeed to customize how memory is allocated. But unless they throw an exception, they do have to actually _allocate_ some memory. If they don't throw, the return value must be a void* to a newly-allocated piece of memory. So what I gather you're trying to do (potentially return a pointer to an already-existing object) isn't acceptable behavior for a custom allocator.You are right. If I return an existing object it will be initialized to default values. I guess that means the solution to a singleton pattern proposed by Burton Radons does not work (http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&g oup=D&artnum=14520) Still, it's a pity that "new ClassType()" cannot be used to transparently return an existing object (conditionally or not). -- Luís Marques
Dec 30 2006
Luís Marques wrote:Hello all. I need to build a class for which there should be only one instance with a given attribute (of type char[]).Isn't this the standard idiom for this kind of keyed singleton pattern? class MyClass { private MyClass[char[]] instances; private this(char[] data) { // Do stuff } public static MyClass getInstance() { if (data in instances) { return instances[data]; } else { MyClass obj = new MyClass(data); instances[data] = obj; return obj; } } } I don't see why a custom allocator ever needs to be involved. --benji
Dec 29 2006
Benji Smith wrote:Luís Marques wrote:[...]Hello all. I need to build a class for which there should be only one instance with a given attribute (of type char[]).Isn't this the standard idiom for this kind of keyed singleton pattern?I don't see why a custom allocator ever needs to be involved. --benjiI think what would be needed is a total replacement for the creation of an object. This would require that this: new ClassName(agrs); translate to something like this: ClassName.opTotalNewReplacment(args); I think that what Luis is looking for is the means to use a singleton class with the standard new syntax. This would be nice for things like templates. template Foo(T) { class Foo { T[] t; this() { t.length = 1; t[0] = new T; // <<<<< //this template can't be used unless new type // construction is allowed } } } That said, I don't yet have an opinion on if this is a good idea.
Dec 29 2006