Using Enums to Replace #define's with Strongly-typed Variables

#define's in C++ code are a terrible way to define collections, but they are commonplace in legacy code. After a few years of refining my approach, this is what I have come up with to replace them.

//Legacy approach (don't do this)
#define BUILDINGTYPE_HOUSE 1
#define BUILDINGTYPE_APARTMENT 4
#define BUILDINGTYPE_OFFICE 9
//buildingType will accept any integer value, even though only 1, 4, & 9 are valid.
void SetBuildingType(int buildingType)
{
//Code inside may compile but could break at runtime.
}
view raw bad.h hosted with ❤ by GitHub
//A better way
namespace BuildingTypes
{
//Typically, explicit enum values are not necessary,
//but they can be helpful when converted legacy #define enumerations to an enum
enum BuildingType
{
House = 1,
Apartment = 4,
Office = 9
};
};
view raw Better.h hosted with ❤ by GitHub
class Consumer
{
private:
BuildingTypes::BuildingType m_BuildingType;
public:
//Use of the enum allows us to strongly-type parameters & return types
//Calling with/returning a value outside of the enum is caught at compile time
BuildingTypes::BuildingType GetBuildingType();
void SetBuildingType(BuildingTypes::BuildingType newType);
}
view raw Consumer.h hosted with ❤ by GitHub
void Consumer2::Build(BuildingTypes::BuildingType buildingType)
{
//Our using statement is local to the method to avoid polluting the
//global namespace and potentially creating a naming conflict with
//another enum (if another enum had a 'House', for example)
using namespace BuildingTypes;
//We could also put this at the top of the .cpp file if we wanted to use
//it in multiple functions. We could also put it in the header file.
//However, that would apply it everywhere the class was imported.
//...Probably not what we want.
//Notice that because of the using statement, we don't have to use
//case BuildingTypes::BuildingType::House:
//It's already obvious from the variable name above that the cases
//are extended message types.
//The resulting switch is not bloated and is easy for the reader to follow.
switch (buildingType)
{
case House:
BuildHouse();
break;
case Apartment:
BuildApartment();
break;
case Office:
BuildOffice();
break;
}
}
view raw consumer2.cpp hosted with ❤ by GitHub

Comments

Popular posts from this blog

Fixing Conan Lock Issues

Initialize With Care

Dude, Where's My Framework?