#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.
Last active
January 20, 2020 20:36
-
-
Save jlschrag/ec2f10776b98a288a0c395ce98fb0481 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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. | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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 | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment