1. Sissejuhatus
C-keelt armastavad paljud programmeerijad selle ajaloolise tausta ja madala taseme kontrolli tõttu. Kuid C pole “objektorienteeritud keel”. See tähendab, et erinevalt Java või C++ keeltest ei toeta C ise objektorienteeritud funktsioone nagu klassid, pärimine ja kapseldamine. Siiski saab ka C-keeles objektorienteeritud programmeerimise kontseptsioone jäljendada ning teatud määral funktsionaalsust saavutada. Selles artiklis selgitame, kuidas saab C-keeles objektorienteeritud programmeerimist rakendada, käsitledes põhimõisteid nagu kapseldamine, pärimine ja polümorfism.
2. Objektorienteerituse põhikontseptsioonid
Objektorienteeritud programmeerimine (OOP) keskendub andmete ja nende töötlemise viisi ühendamisele ühtseks tervikuks. See muudab programmi struktuuri selgemaks ning parandab taaskasutatavust ja hooldatavust. Objektorienteerituse peamised põhimõisted on kapseldamine, pärimine ja polümorfism. Kuigi C-keel neid otse ei toeta, saab neid teatud võtetega imiteerida.
2.1 Kapseldamine
Kapseldamine tähendab, et andmed ja nende töötlemise meetodid (meetodid) ühendatakse üheks üksuseks ning välisest ligipääsust kontrollitakse. C-keeles saab andmeid koondada kasutades struktuure. Struktuur täidab klassi rolli, ühendades mitu andmeväärtust üheks tervikuks.
typedef struct {
int age;
char name[50];
} Person;
Selles struktuuris kapseldatakse Person
andmetüüpi vanus ja nimi. Nii saab Person
struktuuri instantsida ja sellega toimetada.
2.2 Pärimine
C-keeles pole pärimise mõistet, nii et otse vanem-laps suhteid teha ei saa. Kuid kasutades struktuure saab ühe struktuuri liikmena teise struktuuri lisada, mis annab võimaluse pärimisele sarnase mehhanismi loomiseks.
typedef struct {
int age;
} Parent;
typedef struct {
Parent parent;
int studentID;
} Child;
Selles näites sisaldab Child
struktuur Parent
struktuuri, luues niiviisi pseudo-pärimise.
2.3 Polümorfism
Polümorfism tähendab, et sama tegevus võib erinevate objektide puhul toimida erinevalt. C-keeles saab seda saavutada funktsioonipointeritega. Funktsioonipointer on muutuja, mis hoiab funktsiooni aadressi, võimaldades dünaamiliselt kutsuda erinevaid funktsioone.
typedef int (*OperationFunc)(int, int);
int add(int a, int b) {
return a + b;
}
int multiply(int a, int b) {
return a * b;
}
OperationFunc op = add; // Määratakse add-funktsioon
printf("%d", op(3, 4)); // Tulemus: 7
op = multiply; // Muudetakse multiply-funktsiooniks
printf("%d", op(3, 4)); // Tulemus: 12
Nii saab sama funktsioonipointeri abil erinevaid tegevusi teostada.

3. Kuidas C-keeles klassi rakendada
Objektorienteeritud programmeerimise C-keeles rakendamiseks on vaja luua pseudo-klasside mõiste. Selleks ühendatakse struktuurid ja funktsioonipointerid, et luua struktuur, mis meenutab klassi.
3.1 Struktuuri kasutamine klassina
Klassi loomiseks C-keeles kasutatakse struktuuri ning sinna koondatakse andmed ja meetodid. Meetodid määratakse funktsioonidena ning hallatakse struktuuri sees funktsioonipointeritega.
typedef struct {
int age;
void (*setAge)(struct Person*, int);
int (*getAge)(struct Person*);
} Person;
void setAge(struct Person* p, int age) {
p->age = age;
}
int getAge(struct Person* p) {
return p->age;
}
Person person = {0, setAge, getAge};
person.setAge(&person, 25);
printf("Age: %d", person.getAge(&person)); // Tulemus: 25
Selles näites on Person
struktuuril setAge
ja getAge
meetodid ning see käitub peaaegu nagu klass.
4. Meetodi rakendamine
Objektorienteerituse tunnuseks on meetodite olemasolu, mida saab C-keeles imiteerida funktsioonipointerite abil. Nii saab määratleda meetodid struktuuri liikmetena.
typedef struct {
int age;
void (*setAge)(struct Person*, int);
} Person;
void setAge(struct Person* p, int age) {
p->age = age;
}
5. Kokkuvõte ja rakendused
C-keeles on võimalik objektorienteeritust rakendada, kuid kuna keel seda loomupäraselt ei toeta, nõuab see teatavat nutikust. Struktuuride, funktsioonipointerite ja mäluhaldusega saab C-s imiteerida klasside ja pärimise kontseptsioone.