"this" pointer in C (not C++)
I'm trying to create a stack in C for fun, and came up with the idea of using struct to represent the stack. Then I add function pointers to the struct for push() and pop() operations.
So far all is good it seems, but, for the implementation of the push() and pop() functions I need to refer to *this somehow. How can that (can it?) be done?
开发者_运维知识库This is my struct
struct Stack {
int *data;
int current_size;
int max_size;
int (*push)(int);
int (*pop)();
};
And as an example here's push
int push(int val) {
if(current_size == max_size -1)
return 0;
data[current_size] = val;
current_size++;
return 1;
}
As you can imagine, the compiler has no idea what current_size
is, as it would expect something like stack->current_size
.
Is this possible to overcome somehow?
There's no implicit this
in C. Make it explicit:
int push(Stack* self, int val) {
if(self->current_size == self->max_size - 1)
return 0;
self->data[self->current_size] = val;
(self->current_size)++;
return 1;
}
You will of course have to pass the pointer to the struct into every call to push
and similar methods.
This is essentially what the C++ compiler is doing for you when you define Stack
as a class and push
et al as methods.
The typical approach in C is to have functions expect this
as the first parameter.
int push(Stack *self, int val)
{
if (self->current_size == self->max_size -1) return 0;
self->data[self->current_size++] = val;
return 1;
}
This has the added benefit that, unless you need polymorphism, you don't need to put the functions in the stack, because you could just call push(stack, 10)
instead of stack->push(stack,10)
.
C doesn't work like that. It's not an object oriented language. Functions that manipulate data structures need to take a pointer to the structure as an argument.
In header file you can declare static
this
variable
static struct Stack *this;
And then in push
method you can use this
variable
static int push(int val) {
if(this->current_size == this->max_size - 1)
return 0;
this->data[this->current_size] = val;
(this->current_size)++;
return 1;
}
The caveat is you have to manually set this
variable through some method before you want to invoke other methods, eg:
struct Stack {
struct Stack (*_this)(struct Stack *); // <-- we create this method
int *data;
int current_size;
int max_size;
int (*push)(int);
int (*pop)();
};
And then we can implement _this
method as
static struct Stack *_this(struct Stack *that)
{
retrun this = that;
}
The example:
struct Stack stack1, stack2;
... some initialization ...
stack1->_this(&stack1)->push(0);
stack1->push(1);
stack1->push(2);
stack2->_this(&stack2);
stack2->push(10);
stack2->push(20);
Your function pointers aren't methods so they don't have any information about the calling object. The only way to do what you want is to either pass in a pointer to the object, or make that pointer global (the latter is not recommended).
Obviously you can have a Stack * member in the struct and then just initialize it with the address of the struct before you use the function pointers. Then make the Stack * a parameter on the function pointers.
Since your are going to have only one Stack structure (that you named stack, apparently), you could define it as a global variable. This would allow pop/push to refer to the stack variable directly.
You would do something like:
stack.current_size += 4;
or use the -> operator if you decide to declare stack as a memory pointer to Stack.
精彩评论