C++ Dynamic Initialization | 'Dynamic Initialization' Guide
이 글의 핵심
C++ Dynamic Initialization - "Dynamic Initialization" guide. Explains what is dynamic initialization?, static variable initialization, and practical examples with production code.
What is Dynamic Initialization?
Dynamic initialization is a method of initializing variables through function calls or expression evaluation at runtime. Used when value cannot be known at compile-time.
int getValue() { return 42; }
int x = getValue(); // Dynamic initialization (runtime)
constexpr int y = 42; // Constant initialization (compile-time)
Why needed?:
- Flexibility: Initialize with runtime values (file, network, user input)
- Complex logic: Complex initialization logic like constructors, function calls
- Dependencies: Depend on other variables or external state
Here is a simple C++ code example. Try running the code directly to check its operation.
// When dynamic initialization is needed
int port = loadConfigFromFile(); // Read from file
std::string name = getUserInput(); // User input
Database db("localhost", port); // Constructor call
Initialization Comparison:
| Initialization Method | Timing | Example |
|---|---|---|
| Constant initialization | Compile-time | constexpr int x = 10; |
| Dynamic initialization | Runtime | int x = getValue(); |
| Zero initialization | Program load | static int x; |
Static Variable Initialization
Below is an implementation example using C++. Understand the role of each part while examining the code.
int compute() {
return 42;
}
// Dynamic initialization
int global = compute();
void func() {
static int local = compute(); // On first call
}
Static Variable Initialization Timing:
- Global variables: Initialized before
main()execution - Static local variables: Initialized on first call (lazy initialization)
#include <iostream>
int initGlobal() {
std::cout << "Global variable initialization\n";
return 100;
}
int global = initGlobal(); // Executed before main()
void func() {
static int local = []() {
std::cout << "Static local variable initialization\n";
return 200;
}();
}
int main() {
std::cout << "main started\n";
func(); // "Static local variable initialization"
func(); // No output (already initialized)
}
// Output:
// Global variable initialization
// main started
// Static local variable initialization
Production Recommendation:
- Global variables: Avoid if possible (initialization order problems)
- Static local variables: Use for Singleton, lazy initialization
Practical Examples
Example 1: Static Local Variable
Here is detailed implementation code using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.
class Database {
public:
Database() {
std::cout << "DB connection" << std::endl;
}
};
Database& getDB() {
static Database db; // Initialize on first call
return db;
}
int main() {
getDB(); // "DB connection"
getDB(); // No output (already initialized)
}
Example 2: Singleton
Here is detailed implementation code using C++. Define a class to encapsulate data and functionality. Understand the role of each part while examining the code.
class Singleton {
Singleton() {
std::cout << "Created" << std::endl;
}
public:
static Singleton& getInstance() {
static Singleton instance; // Thread-safe (C++11)
return instance;
}
};
int main() {
auto& s1 = Singleton::getInstance(); // "Created"
auto& s2 = Singleton::getInstance(); // No output
}
Example 3: Initialization Order Problem
Below is an implementation example using C++. Understand the role of each part while examining the code.
// file1.cpp
int x = compute1();
// file2.cpp
extern int x;
int y = x + 1; // x may not be initialized yet
// ✅ Solve with static variable in function
int& getX() {
static int x = compute1();
return x;
}
int y = getX() + 1; // Order guaranteed
Example 4: Lazy Initialization
Here is detailed implementation code using C++. Define a class to encapsulate data and functionality and perform branching with conditionals. Understand the role of each part while examining the code.
class Resource {
public:
Resource() {
std::cout << "Resource created" << std::endl;
}
};
Resource& getResource() {
static Resource res; // Created on first use
return res;
}
int main() {
const bool needResource = true;
// Not created if Resource not used
if (needResource) {
getResource();
}
}
Thread Safety
Below is an implementation example using C++. Try running the code directly to check its operation.
// C++11: Static local variable initialization is thread-safe
void func() {
static int x = compute(); // Only one thread initializes
}
// C++03: Not thread-safe
C++11 Thread Safety Guarantee:
From C++11, static local variable initialization is automatically thread-safe. Compiler internally uses mutex to ensure only one thread initializes.
#include <thread>
#include <iostream>
int expensiveInit() {
std::cout << "Init started (thread " << std::this_thread::get_id() << ")\n";
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Init completed\n";
return 42;
}
void func() {
static int value = expensiveInit(); // Thread-safe
std::cout << "Value: " << value << '\n';
}
int main() {
std::thread t1(func);
std::thread t2(func);
std::thread t3(func);
t1.join();
t2.join();
t3.join();
}
// Output:
// Init started (thread ...)
// Init completed
// Value: 42
// Value: 42
// Value: 42
// (Initialization executed only once)
Summary
Key Points
- Dynamic initialization: Runtime initialization via function calls
- Global variables: Initialized before main()
- Static local variables: Lazy initialization on first call
- Thread safety: C++11 guarantees thread-safe static local initialization
- Order problems: Avoid global variable dependencies
When to Use
✅ Use dynamic initialization when:
- Need runtime values
- Complex initialization logic
- Lazy initialization (static local)
- Singleton pattern
❌ Don’t use when:
- Can use constexpr (compile-time)
- Global variable dependencies
- Order-dependent initialization
Best Practices
- ✅ Prefer static local variables over globals
- ✅ Use for Singleton pattern
- ✅ Leverage C++11 thread safety
- ❌ Don’t create global variable dependencies
- ❌ Don’t ignore initialization order
Related Articles
Master dynamic initialization for safer C++ code! 🚀