Phần 1
1. Goal
After learning enum class, you should understand:
1. Why C++11 introduced `enum class`.
2. How it is safer than old-style `enum`.
3. The minimum syntax.
4. Common mistakes when using scoped enums.
5. How `enum class` improves domain modeling in real-world C++ code.Phần 2
2. What Problem Does It Solve?
Old-style enum has two major problems:
1. Enum names leak into the surrounding scope.
2. Enum values can implicitly convert to integers.Example with old-style enum:
enum Side { Buy, Sell };The names Buy and Sell are placed directly into the surrounding scope.
C++11 introduced enum class to make enums safer and clearer.
Main idea:
enum class creates scoped and strongly typed enum values.Phần 3
3. Minimum Syntax
Basic syntax:
enum class Side {
Buy,
Sell
};Use enum values with the enum name:
Side side = Side::Buy;Compare values:
if (side == Side::Buy) {
// buy side
}Specify the underlying type:
enum class Side : std::uint8_t {
Buy,
Sell
};Phần 4
4. Why enum class Is Better Than Old enum
Old-style enum
enum Side { Buy, Sell };Problems:
Buy and Sell leak into the outer scope.
They can implicitly convert to int.Modern C++ enum class
enum class Side { Buy, Sell };Benefits:
Values are scoped: Side::Buy, Side::Sell.
No implicit conversion to int.
Safer and more readable.Phần 5
5. Common Mistakes
5.1. Forgetting the scope
Wrong:
Side side = Buy;Correct:
Side side = Side::Buy;5.2. Expecting implicit conversion to int
Wrong:
int x = Side::Buy;Correct if conversion is really needed:
int x = static_cast<int>(Side::Buy);5.3. Overusing raw integers instead of domain enums
Avoid:
int side = 1;Prefer:
Side side = Side::Buy;This makes code safer and easier to understand.
Phần 6
6. When Should You Use enum class?
Use enum class when a variable can only have a small fixed set of valid states.
Examples:
Order side: Buy / Sell
Order status: New / Filled / Cancelled
Market data type: Trade / Quote
Connection state: Connected / DisconnectedAvoid raw integers or strings when the valid values are fixed and known.
Phần 7
7. Notes for Trading / Performance-Sensitive Code
Trading code often has domain states:
Side
OrderType
OrderStatus
TimeInForce
Exchange
MessageTypeenum class makes these states explicit and type-safe.
Example idea:
Side::Buy is clearer and safer than int side = 1.
OrderStatus::Filled is clearer than string status = "FILLED".It also helps avoid passing the wrong kind of value to a function.
Phần 8
8. End-of-Day Checklist
You should remember:
enum class = scoped enum + strong typingYou should be able to answer:
1. Why is `enum class` safer than old `enum`?
2. Why do we write `Side::Buy` instead of `Buy`?
3. Can `enum class` convert to int automatically?
4. When should you use `static_cast<int>`?
5. Why is `enum class` useful in trading systems?Phần 9
9. Conclusion
enum class is a safer replacement for old-style enums.
The key idea:
Use enum class to represent a fixed set of domain states clearly and safely.
Prefer Side::Buy over raw integers or unscoped enum values.:::
Mã mẫu hoàn chỉnh
cpp11/5_enum class/main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
enum class Side {
Buy,
Sell
};
enum class OrderType {
Market,
Limit
};
enum class OrderStatus {
New,
Filled,
Cancelled,
Rejected
};
struct Order {
int id;
std::string symbol;
Side side;
OrderType type;
OrderStatus status;
double price;
int quantity;
};
std::string toString(Side side) {
switch (side) {
case Side::Buy:
return "Buy";
case Side::Sell:
return "Sell";
}
return "Unknown";
}
std::string toString(OrderType type) {
switch (type) {
case OrderType::Market:
return "Market";
case OrderType::Limit:
return "Limit";
}
return "Unknown";
}
std::string toString(OrderStatus status) {
switch (status) {
case OrderStatus::New:
return "New";
case OrderStatus::Filled:
return "Filled";
case OrderStatus::Cancelled:
return "Cancelled";
case OrderStatus::Rejected:
return "Rejected";
}
return "Unknown";
}
void printOrder(const Order& order) {
std::cout << "Order ID: " << order.id << '\n';
std::cout << "Symbol: " << order.symbol << '\n';
std::cout << "Side: " << toString(order.side) << '\n';
std::cout << "Type: " << toString(order.type) << '\n';
std::cout << "Status: " << toString(order.status) << '\n';
std::cout << "Price: " << std::fixed << std::setprecision(2)
<< order.price << '\n';
std::cout << "Quantity: " << order.quantity << '\n';
}
bool isActive(OrderStatus status) {
return status == OrderStatus::New;
}
void cancelOrder(Order& order) {
if (isActive(order.status)) {
order.status = OrderStatus::Cancelled;
}
}
int main() {
std::vector<Order> orders = {
{101, "AAPL", Side::Buy, OrderType::Limit, OrderStatus::New, 191.25, 100},
{102, "MSFT", Side::Sell, OrderType::Market, OrderStatus::Filled, 0.00, 50},
{103, "NVDA", Side::Buy, OrderType::Limit, OrderStatus::New, 875.10, 10}
};
std::cout << "Before cancel:\n";
printOrder(orders[0]);
cancelOrder(orders[0]);
std::cout << "\nAfter cancel:\n";
printOrder(orders[0]);
std::cout << "\nAll orders:\n";
for (const auto& order : orders) {
std::cout << order.id << " | "
<< order.symbol << " | "
<< toString(order.side) << " | "
<< toString(order.type) << " | "
<< toString(order.status) << '\n';
}
return 0;
}Tự kiểm tra · không chấm điểm
Bạn đã hiểu những điểm nào?
Đã tự kiểm tra 0/5 mục