www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: class design question (inner classes)

reply coxalan <coxalan web.de> writes:
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
Sep 11 2007
parent Regan Heath <regan netmail.co.nz> writes:
coxalan wrote:
 Regan Heath Wrote:
 
 What about doing it manually/explicitly...

Thanks for the code!

No problem.
 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?

Yep. At first I tried using a static inner class and I wanted to ensure it made a difference to the size.
 * 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.)

I think I put that there because you mentioned something about needing to know how many Inner classes the Outer class was handling, it can be replaced with an int :)
 * 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".

No, if both Outer and Inner are the same type for both "a" and "b" it won't work because the m_Outer will be overwritten with each new Inner.
 With standard D inner classes, that would be no problem.

True, but I can't see how it's possible to get what you want with inner classes. If the inner class is "static" then it has no outer reference, but it also cannot access any non-static members of outer either. If it's not static then it has an outer reference. What you actually want is for the outer reference to be a static member of the outer class, but then how can the inner class find it, unless it has a reference to the outer class. Regan
Sep 11 2007