본문으로 건너뛰기 C++ Dynamic Initialization | 'Dynamic Initialization' Guide

C++ Dynamic Initialization | 'Dynamic Initialization' Guide

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 MethodTimingExample
Constant initializationCompile-timeconstexpr int x = 10;
Dynamic initializationRuntimeint x = getValue();
Zero initializationProgram loadstatic int x;

Static Variable Initialization

int compute() {
    return 42;
}

// Dynamic initialization
int global = compute();

void func() {
    static int local = compute();  // On first call
}

Static Variable Initialization Timing:

  1. Global variables: Initialized before main() execution
  2. 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

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

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

// 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

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

// 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

  1. Dynamic initialization: Runtime initialization via function calls
  2. Global variables: Initialized before main()
  3. Static local variables: Lazy initialization on first call
  4. Thread safety: C++11 guarantees thread-safe static local initialization
  5. 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

Master dynamic initialization for safer C++ code! 🚀


Frequently Asked Questions (FAQ)

Q. When would I use this in practice?

A. Everything about C++ Dynamic Initialization : from basic concepts to practical applications.

Q. What should I read before this?

A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.

Q. Where can I study this more deeply?

A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers C++, dynamic-initialization, static, runtime, initialization.