I come from an OPP background and have struggle with what is the optimal (speed wise) way of implementing what I need.
I define the below struct:
struct Vehicle {
int A;
int B;
}
And I want some other struct like:
// is Vehicle
struct Bike {
int C;
}
// is Vehicle
struct Car {
int D;
}
In the end I have a function:
void f(struct Vehicle vehicles[], int nVehicles) {
for(int i=0;i<nVehicles; i){
struct Vehicle v = vehicles[i];
//if v is a car do something
//else if a bike do something else
}
}
that takes an array of Vehicle
as parameter and these can be either bike
either car
.
In f
I need to access A
,B
and C
if a bike
or D
if a car.
How do I implement this?
For now I have done the below which works but I think is very inefficient and bad:
struct Bike {
int A;
int B;
int C;
}
struct Car {
int A;
int B;
int D;
}
struct Vehicle {
char* vehicleType;
struct Bike;
struct Car;
}
void f(struct Vehicle vehicles[], int nVehicles) {
for(int i=0;i<nVehicles; i){
struct Vehicle v = vehicles[i];
char *vehicleType = v.vechicleType
if(strcmp(vehicleType, "Bike")==0) {
// Do something
} else if(strcmp(vehicleType, "Car")==0) {
// Do something else
}
}
}
(NB: please no typedef, see: https://stackoverflow.com/a/4566358/19142731)
CodePudding user response:
It's mostly been said in the comments, but here's a workup of what's been said (and I have not used any typedef
s, but personally I would).
So, point 1, use an enum
for your vehicleType
, and point 2, a vehicle
can't be both a Car
and a Bike
so this is a good place to use a union
to save space.
All of which leads us to something like this:
enum VEHICLE_TYPE { bike, car };
struct Vehicle
{
enum VEHICLE_TYPE vehicleType;
union u
{
struct Bike
{
int top_speed;
} Bike;
struct Car
{
int number_of_seats;
} Car;
} u;
} Vehicle;
And you might then do:
int main ()
{
struct Vehicle v;
v.vehicleType = bike;
v.u.Bike.top_speed = 100;
...
}
Most people (including myself!) would probably disagree with how I've (mis-) used upper and lower case here. Sorry, bit rushed.
CodePudding user response:
I would use C-style cast to pointer:
struct Bike {
int A;
int B;
int C;
};
struct Car {
int A;
int B;
int D;
};
struct Vehicle {
const char* vehicleType;
};
void f(struct Vehicle vehicles[], int nVehicles) {
for (int i = 0; i < nVehicles; i) {
Vehicle v = vehicles[i];
const char* vehicleType = v.vehicleType;
if (strcmp(vehicleType, "Bike") == 0) {
Bike* b = (Bike*)&v;
//Do what you need with 'Bike' now
b->A = 1; //For example
b->B = 1; //For example
b->C = 1; //For example
}
else if (strcmp(vehicleType, "Car") == 0) {
Car* c = (Car*)&v;
//Do what you need with 'Car' now
c->D = 2; //For example
}
}
}