Skip to content

Commit 0775a03

Browse files
author
Christian Howe
committed
Initial commit
0 parents  commit 0775a03

File tree

9 files changed

+230
-0
lines changed

9 files changed

+230
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
build:
2+
gcc main.c animal.c dog.c -o test
3+
4+
memcheck:
5+
valgrind ./test
6+
7+
clean:
8+
rm test

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Object Oriented Test
2+
3+
Since there are so many ways to make object oriented C code, I decided to try
4+
out a few different methods and develop my favorite one. This is the result of
5+
that experiment. It's a simple example with a few classes and a simple class
6+
structure, with a parent Animal class and a child Dog class. The Animal class
7+
has a virtual method that the Dog class overwrites. It's a pretty simple method
8+
to do some really cool things, IMO. Other ways seemed to involve a lot more
9+
boilerplate code and didn't really look as pretty as I would have liked.
10+
11+
## Build it
12+
13+
```
14+
make
15+
```
16+
17+
## Try it
18+
19+
```
20+
./test
21+
```
22+
23+
## Clean it
24+
25+
```
26+
make clean
27+
```
28+
29+
## Check it for memory leaks (requires valgrind)
30+
31+
```
32+
make memcheck
33+
```

animal.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "animal.h"
2+
3+
int animal_new(animal_t* self, const char* type) {
4+
if (type == NULL) {
5+
return ERROR_VAL;
6+
}
7+
8+
self->type = malloc(strlen(type)+1);
9+
strcpy(self->type, type);
10+
11+
return SUCCESS_VAL;
12+
}
13+
14+
int animal_delete(animal_t* self) {
15+
if (self->type != NULL) {
16+
free(self->type);
17+
self->type = NULL;
18+
}
19+
20+
return SUCCESS_VAL;
21+
}
22+
23+
void animal_speak(animal_t* self) {
24+
if (self->vtable.speak) {
25+
return self->vtable.speak(self);
26+
}
27+
28+
printf("This %s cannot speak!", self->type);
29+
}

animal.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef ANIMAL_H
2+
#define ANIMAL_H
3+
4+
#include <stdlib.h>
5+
#include <stdio.h>
6+
#include <string.h>
7+
8+
#include "error.h"
9+
10+
typedef struct {
11+
struct {
12+
void (*speak)(void* self);
13+
} vtable;
14+
15+
char* type;
16+
} animal_t;
17+
18+
int animal_new(animal_t* self, const char* type);
19+
20+
int animal_delete(animal_t* self);
21+
22+
void animal_speak(animal_t* self);
23+
24+
// Create a nice structure to expose them in :D
25+
static const struct {
26+
int (*new)(animal_t*, const char*);
27+
int (*delete)(animal_t*);
28+
29+
void (*speak)(animal_t*);
30+
} Animal = {
31+
.new = &animal_new,
32+
.delete = &animal_delete,
33+
.speak = &animal_speak,
34+
};
35+
36+
#endif // ANIMAL_H

dog.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "dog.h"
2+
3+
void dog_speak (void* _self) {
4+
dog_t* self = _self;
5+
printf("'woof!' says the %s %s dog!\n", self->size, self->furColor);
6+
}
7+
8+
int dog_new (dog_t* self, const char* furColor, const char* size) {
9+
if (furColor == NULL || size == NULL) {
10+
return ERROR_VAL;
11+
}
12+
13+
Animal.new(&(self->super), "dog");
14+
15+
self->super.vtable.speak = &dog_speak;
16+
17+
self->furColor = malloc(strlen(furColor) + 1);
18+
strcpy(self->furColor, furColor);
19+
20+
self->size = malloc(strlen(size) + 1);
21+
strcpy(self->size, size);
22+
23+
return SUCCESS_VAL;
24+
}
25+
26+
int dog_delete (dog_t* self) {
27+
Animal.delete(&self->super);
28+
29+
if (self->furColor != NULL) {
30+
free(self->furColor);
31+
self->furColor = NULL;
32+
}
33+
if (self->size != NULL) {
34+
free(self->size);
35+
self->size = NULL;
36+
}
37+
38+
return SUCCESS_VAL;
39+
}
40+
41+
const char* dog_getFurColor (dog_t* self) {
42+
return self->furColor;
43+
}
44+
45+
const char* dog_getSize (dog_t* self) {
46+
return self->size;
47+
}

dog.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef DOG_H
2+
#define DOG_H
3+
4+
#include <stdlib.h>
5+
#include <string.h>
6+
7+
#include "error.h"
8+
9+
// INHERITS FROM ANIMAL
10+
#include "animal.h"
11+
12+
typedef struct {
13+
animal_t super;
14+
char* furColor;
15+
char* size;
16+
} dog_t;
17+
18+
// Creates a dog, takes fur color and size. Returns pointer to dog. This copies
19+
// the strings.
20+
int dog_new (dog_t* self, const char* furColor, const char* size);
21+
22+
// Deletes a dog. Takes pointer to dog created with dog_ctor D:
23+
int dog_delete (dog_t* self);
24+
25+
// Gets the fur color passed to the constructor, takes pointer to dog created
26+
// with dog_ctor.
27+
const char* dog_getFurColor (dog_t* self);
28+
29+
// Gets the size passed to the constructor, takes pointer to dog created with
30+
// dog_ctor.
31+
const char* dog_getSize (dog_t* self);
32+
33+
// Create a nice structure to expose them in :D
34+
static const struct {
35+
int (*new)(dog_t*, const char* furColor, const char* size);
36+
int (*delete)(dog_t*);
37+
38+
const char* (*getFurColor)(dog_t*);
39+
const char* (*getSize)(dog_t*);
40+
} Dog = {
41+
.new = &dog_new,
42+
.delete = &dog_delete,
43+
.getFurColor = &dog_getFurColor,
44+
.getSize = &dog_getSize
45+
};
46+
47+
#endif // DOG_H

error.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef ERROR_H
2+
#define ERROR_H
3+
4+
#define ERROR_VAL -1
5+
#define SUCCESS_VAL 0
6+
#define ERROR (err) { errno = (err); }
7+
8+
#endif // ERROR_H

main.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <stdarg.h>
2+
#include <stdlib.h>
3+
#include <stdio.h>
4+
#include <string.h>
5+
#include <errno.h>
6+
7+
#include "dog.h"
8+
9+
int main (int argc, char* argv[]) {
10+
dog_t* dog = malloc(sizeof(dog_t));
11+
Dog.new(dog, "white", "small");
12+
13+
printf("The %s dog has %s fur!\n", Dog.getSize(dog), Dog.getFurColor(dog));
14+
15+
Animal.speak((animal_t*)dog);
16+
17+
Dog.delete(dog);
18+
free(dog);
19+
20+
return 0;
21+
}

0 commit comments

Comments
 (0)