SrcForge

Lesson 60

Enums and Typedef

Covers defining enums, assigning custom values, scoped enums (enum class), typedef for types, pointers, and structures, and using vs typedef.

Lesson content

What are Enums and Typedef in C++?

Enums and Typedef in C++ are language features that improve code readability, maintainability, and organization.

An enumeration (enum) allows you to define a collection of named constant values. Instead of using hard-coded numbers throughout your program, you can use meaningful names.

A typedef allows you to create an alias (another name) for an existing data type. This makes complex type declarations easier to read and maintain.

Think of an enum as assigning names to numbered lockers. Instead of saying "Locker 3," you can say "ScienceLocker." Similarly, think of typedef as giving a person a nickname. The person remains the same, but the nickname is easier to remember.

Why do they exist?

Without enums, programmers often use magic numbers that make code difficult to understand. Without typedef, long and complicated type names can make programs harder to read. Both features help make code cleaner, safer, and easier to maintain.

Real-world use cases

  • Representing days of the week
  • Traffic light systems
  • User roles and permissions
  • Game states
  • Network protocol constants
  • Simplifying complex pointer declarations
  • Creating readable aliases for custom data types

Prerequisites

  • Variables
  • Data types
  • Constants
  • Functions
  • Basic classes (recommended)
  • Basic pointers (helpful)

What is an enum?

An enum (enumeration) is a user-defined data type that consists of a fixed set of named constants.

enum EnumName
{
    VALUE1,
    VALUE2,
    VALUE3
};

// Example:
enum Day
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
};

By default, the values are assigned automatically starting from 0: Monday is 0, Tuesday is 1, Wednesday is 2, Thursday is 3, Friday is 4, Saturday is 5, and Sunday is 6.

Assigning custom values

You can assign your own integer values. Subsequent values continue incrementing automatically unless explicitly specified.

enum ErrorCode
{
    SUCCESS = 0,
    WARNING = 100,
    ERROR = 200
};

Scoped enums (enum class)

Modern C++ introduced scoped enums using enum class. Advantages include better type safety, preventing name conflicts, and requiring explicit scope.

enum class Color
{
    Red,
    Green,
    Blue
};

Color c = Color::Green;

What is typedef?

A typedef creates an alias for an existing type.

typedef existingType aliasName;

// Example:
typedef unsigned long ulong;

// Now:
ulong number = 5000;

// is equivalent to:
unsigned long number = 5000;

Typedef with structures

typedef struct
{
    int id;
    double salary;
} Employee;

// Now you can write:
Employee emp;

Typedef with pointers

Typedef makes pointer declarations easier to read.

typedef int* IntPointer;

// Now:
IntPointer p;

// is equivalent to:
int* p;

using vs typedef

Modern C++ recommends using 'using' because it is more flexible. typedef was introduced in C and doesn't support template aliases, while using was introduced in C++11, supports template aliases, and is recommended in modern C++.

using Integer = int;

Example 1: Basic enum

#include <iostream>
using namespace std;

enum Day
{
    Monday,
    Tuesday,
    Wednesday
};

int main()
{
    Day today = Tuesday;

    cout << today << endl;

    return 0;
}

// Output: 1

Example 2: Enum class

#include <iostream>
using namespace std;

enum class TrafficLight
{
    Red,
    Yellow,
    Green
};

int main()
{
    TrafficLight signal = TrafficLight::Green;

    if (signal == TrafficLight::Green)
    {
        cout << "Go";
    }

    return 0;
}

// Output: Go

Example 3: Typedef

#include <iostream>
using namespace std;

typedef unsigned long ulong;

int main()
{
    ulong population = 1500000;

    cout << population << endl;

    return 0;
}

// Output: 1500000

Example 4: Typedef with pointer

#include <iostream>
using namespace std;

typedef int* IntPointer;

int main()
{
    int value = 25;

    IntPointer ptr = &value;

    cout << *ptr << endl;

    return 0;
}

// Output: 25

Example 5: Enum class with switch

#include <iostream>
using namespace std;

enum class Permission
{
    Read,
    Write,
    Execute
};

int main()
{
    Permission user = Permission::Write;

    switch (user)
    {
        case Permission::Read:
            cout << "Read Access";
            break;

        case Permission::Write:
            cout << "Write Access";
            break;

        case Permission::Execute:
            cout << "Execute Access";
            break;
    }

    return 0;
}

// Output: Write Access

Common mistakes and pitfalls

  • Using magic numbers instead of enums. Fix: use meaningful enum values
  • Using plain enum when type safety is required. Fix: prefer enum class
  • Forgetting scope with enum class. Fix: use EnumName::Value
  • Creating confusing typedef names. Fix: use descriptive aliases
  • Assuming typedef creates a new type. Fix: it only creates another name
// Wrong
int status = 2;

if (status == 2)
{
    cout << "Error";
}

// Correct
enum Status
{
    Success,
    Warning,
    Error
};

Status status = Error;

if (status == Error)
{
    cout << "Error";
}

Best practices

  • Prefer enum class over plain enum in modern C++
  • Use enums instead of magic numbers
  • Group related constants using enumerations
  • Give enum values meaningful names
  • Prefer using instead of typedef in new C++ projects
  • Use typedef or using to simplify long type declarations
  • Keep aliases descriptive and easy to understand
  • Avoid creating unnecessary aliases for simple types like int

When not to use this

Avoid enums when values are not fixed at compile time, when you need to associate behavior directly with values, or when a class or structure is more appropriate.

Avoid typedef (or using) when the alias makes the code less clear, the original type is already simple and readable, or excessive aliases make maintenance more difficult.

Summary

  • Enums and Typedef in C++ improve readability and maintainability
  • Enums define a set of named constant values
  • Enum values are integers by default unless assigned explicitly
  • enum class provides better type safety and avoids name collisions
  • typedef creates an alias for an existing type
  • using is the modern replacement for most typedef use cases
  • Type aliases simplify complex declarations, especially pointers and templates
  • Use enums to replace magic numbers and improve code clarity

Frequently asked questions

What is an enum in C++?

An enum is a user-defined type consisting of a fixed set of named constant values, making code more readable than using raw integers.

What is the difference between enum and enum class?

A plain enum places its enumerator names in the surrounding scope and can implicitly convert to integers. An enum class keeps enumerator names scoped and provides stronger type safety.

What is typedef used for?

typedef creates an alias for an existing data type, making long or complex type declarations easier to read.

Is using better than typedef?

Yes. In modern C++, using is generally preferred because it is easier to read and supports template aliases.

Does typedef create a new data type?

No. typedef only creates another name (alias) for an existing type; it does not define a completely new type.