class design question (inner classes)

coxalan coxalan at web.de
Tue Sep 11 12:57:19 PDT 2007


Regan Heath Wrote:

> What about doing it manually/explicitly...

Thanks for the code!
 
> import std.stdio;
> import std.string;
> import std.c.stdlib;
> 
> class Outer
> {
> 	Inner[] m_Data;
>   	uint 	m_Degree;
>   	
>   	this(uint d) { m_Degree = d; }
>   	
> 	Inner allocate(uint[] data)
> 	{
> 		m_Data ~= new Inner(this, data);
> 		return m_Data[$-1];
> 	}
> 	
> 	new(uint size)
> 	{
> 		writefln("Outer new %d", size);
> 		return malloc(size);
> 	}
> 	
> 	delete(void *p)
> 	{
> 		free(p);
> 	}
> }
> 
> class Inner
> {
> 	static Outer 	m_Outer;
> 	uint 		m_Data[];
> 	
> 	this(Outer o, uint[] data = null) {
> 		m_Outer = o;		
> 		m_Data.length = m_Outer.m_Degree;		
> 		if (data !is null)
> 		{
> 			m_Data[0..$] = data[0..m_Data.length];
> 		}
> 	}
> 	
> 	Inner opMul(Inner b)
> 	{
> 		Inner res = new Inner(m_Outer);
> 		foreach(int i, uint val; b.m_Data)
> 		{
> 			res.m_Data[i] = m_Data[i] * b.m_Data[i];
> 		}
> 		return res;
> 	}
> 	
> 	new(uint size)
> 	{
> 		writefln("Inner new %d", size);
> 		return malloc(size);
> 	}
> 	
> 	delete(void *p)
> 	{
> 		free(p);
> 	}
> 	
> 	string toString()
> 	{
> 		return format("%s", m_Data);
> 	}
> }
> 
> void main()
> {
> 	Outer o = new Outer(3);
> 	Inner a = o.allocate([0,1,2]);
> 	Inner b = o.allocate([1,2,3]);
> 	Inner c = a * b;
> 	writefln(c);
> }

A few questions/remarks on this:
* Is there a reason for overloading new and delete besides that you want to display the size of the objects?
* Why the member data
Inner[] m_Data;
in the outer class? By this no links are stored in the Outer objects any more, but now the Inner object stores links, so nothing is won. But in my opinion this line can simply be dropped. (Of course the other line where the links actually get stored must then be modified, too.)
* To execute
m_Outer = o;
always when a new Inner object is created is a little overhead ;-).

> Of course, if you use Inner with another Outer class it will overwrite
> the static m_Outer and fail horribly...

> But maybe we can get round this by using templates...
> 
> class Inner(T)
> {
>    static T m_Outer;
> }
> 
> That way, if you use say..
> 
> Inner!(Outer) a;
> Inner!(Outer) b;
> Inner!(Outer) c;
> 
> Inner!(Bob) d;
> Inner!(Bob) e;
> 
> Inner!(Fred) f;
> 
> You will get a static m_Outer for each combination, thus 3 for the code 
> above.

But I guess it is still not possible to have
Outer a;
Outer b;
and then Inner objects of "a" as well as of "b".

With standard D inner classes, that would be no problem.

Greetings,

coxalan



More information about the Digitalmars-d mailing list