Accessing a field of a containing class from within a nested class

Charles Hixson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Apr 1 16:13:21 PDT 2015


Yess.....but there are LOTS of nodes/BTree, and each node would need to 
check whether the btFile was already initialized, et (ugh!) cetera.  So 
while possible, that's an even worse answer than depending on people 
closing the BTree properly.  I *am* going to separate the close routine 
from the destructor, so that it can be closed manually, and if not the 
destructor is going to print a warning message if the file is still open 
when it's called, but this isn't the best design.  This design calls for 
users of what is essentially a library routine to remember to properly 
close it...or to hope that the destructor gets called before the program 
quits.

In a practical sense, since I'm probably going to be the only user of 
the code, making BTree a class should be ok, but it feels like a bad 
design decision.  I don't want to make the file a static member of the 
Node class (which would answer some of the problems) because that would 
prevent there being more than one BTree open at a time, and I expect to 
need at least two of them, and possibly more.  Were I to do that I might 
as well make it a file level variable.

So the ways to handle lack of a determinate close to the file are all 
clumsy, and a bit error prone.  But I think having a file handle in each 
Node would be MUCH worse.  How could you *ever* know when to close it, 
as Nodes are being opened and freed all the time.  And most of the time 
many are open at once.  Additionally, all the Nodes being closed doesn't 
mean the BTree is closed (though that's the most likely reason) so you 
can't even use a global counter.

OTOH, this is still in the design stage, so if a good answer were to be 
available, now would be the best time to put it in.  (FWIW both the Key 
and the Data will be required to pass !hasIndirections!(T). I'm not 
planning a truly general BTree.  In my test version the Key is a ulong 
and the Data is a struct containing only ulongs and ints.)

On 04/01/2015 03:03 PM, Ali Çehreli via Digitalmars-d-learn wrote:
> On 04/01/2015 11:25 AM, Charles Hixson via Digitalmars-d-learn wrote:> 
> The class Node is contained within the struct BTree.
> > The field   btFile is contained within the struct BTree.
> > The statement is within a function within the Node class.
> >
> > I've tried many variations, here are a few:
> >
> > btFile.write(self.nodeId, cast(void*)&(self));
> > results in:
> > need 'this' for 'btFile' of type 'BlockFile'
> >
> > this.btFile.write(self.nodeId, cast(void*)&(self));
> > results in:
> > Error: no property 'btFile' for type 'btplus.BTree.Node'
> >
> > this.BTree.btFile.write(self.nodeId, cast(void*)&(self));
> > results in:
> >   Error: constructor btplus.BTree.this (string fName) is not callable
> > using argument types (Node)
> >
> > Perhaps BTree needs to be a class?  I made it a struct because I 
> want it
> > to definitely close properly when it
> > goes out of scope.
>
> Can you modify the definition of Node? If so, perhaps it's possible 
> construct Node objects with a reference to its btFile:
>
> import std.stdio;
>
> class Node
> {
>     int *btFile;
>
>     this(int *btFile)
>     {
>         this.btFile = btFile;
>     }
>
>     void foo()
>     {
>         writeln(*btFile);
>     }
> }
>
> struct BTree
> {
>     int btFile;
>     Node node;
>
>     this(int btFile)
>     {
>         this.btFile = btFile;
>         this.node = new Node(&this.btFile);
>     }
> }
>
> void main()
> {
>     auto bt = BTree(42);
>     bt.node.foo();
> }
>
> Ali
>
>



More information about the Digitalmars-d-learn mailing list