digitalmars.D.learn - Accessing a field of a containing class from within a nested class
- Charles Hixson via Digitalmars-d-learn (17/17) Apr 01 2015 The class Node is contained within the struct BTree.
- anonymous (2/3) Apr 01 2015 yes
- Charles Hixson via Digitalmars-d-learn (4/7) Apr 01 2015 Thanks.
- Gary Willoughby (3/6) Apr 01 2015 Maybe `scoped` can help:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (33/49) Apr 01 2015 Can you modify the definition of Node? If so, perhaps it's possible
- Charles Hixson via Digitalmars-d-learn (30/85) Apr 01 2015 Yess.....but there are LOTS of nodes/BTree, and each node would need to
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.
Apr 01 2015
On Wednesday, 1 April 2015 at 18:26:49 UTC, Charles Hixson wrote:Perhaps BTree needs to be a class?yes
Apr 01 2015
On 04/01/2015 11:39 AM, anonymous via Digitalmars-d-learn wrote:On Wednesday, 1 April 2015 at 18:26:49 UTC, Charles Hixson wrote:Thanks. Sigh. I was hoping to preserve the determinate closing that one gets with a struct.Perhaps BTree needs to be a class?yes
Apr 01 2015
On Wednesday, 1 April 2015 at 18:26:49 UTC, Charles Hixson wrote: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.Maybe `scoped` can help:
Apr 01 2015
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
Apr 01 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 Iwant itto 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
Apr 01 2015