I'm not sure what I'm trying to do is called encapsulation, but this is the concept of OOP. I implement a binary tree and in particular the insert function:
typedef struct __node* tree; typedef struct __node { void* data; tree l,r; } node; typedef struct {int (*cmp)(void* a,void* b); tree root;} avl_tree; .... void tree_insert(tree node, tree* root, int (*cmp)(void* a,void* b)) { if (*root==NULL) { *root=node; return; } int c1 = cmp(node->data, (*root)->data); if (c1==-1) tree_insert(node, &((*root)->l), cmp); } tree tree_new_node(void*data){ tree a = malloc(...); ... return a; } void avl_insert(void* data, avl_tree* a) { tree_insert(tree_new_node(data), &(a->root), a->cmp); .... }
The module should be used through the avl_insert function, which is pointed to the corresponding balanced avl_tree tree, which contains a pointer to an unprocessed tree, as well as a pointer to a comparator. Now it should obviously call tree insert , and tree_insert should have access to the comparator, as well as to the node that I am inserting now. The function works on a binary tree, so it is naturally recursive. However, if I give it a comparator and the current node as parameters, they will be passed with every recursive call that is not needed, since they will always be the same.
I would not want to do this. I could not come up with a clean and pleasant solution. Here are the options I could think of:
Use the C ++ class and use the tree_insert function as a method of the avl_tree class. Then it will have access to the comparator using the this pointer. The problem with this solution is that I want to use C not C ++. In addition, it will not eliminate the passing of the current node parameter.
Use static members inside a function (or global data). I am not sure that I can initialize them each time avl_insert called. In addition, this solution is not thread safe.
Now that I think about it, it is very simple to implement in a functional programming language. Interestingly, this is a fundamental problem with C, or I just don't know how to do this. What will be the cleanest way to achieve this?
Thanks!
After I thought about Victor Sorokin, I read about the this pointer, and it turns out that this is an implicit parameter in every call to the member function. Now when I think about it, this is the only logical solution. Each call to the tree_insert function must know the address of the structure in which it works. Even in a functional language, you could not escape this extra pointer ...
A possible solution would be to keep a pointer to the main tree structure in each node ..
So this is a fundamental "problem."