TIL: Explicit๊ณผ Mutable

๋ฐ•์ถ˜ํŒ”ยท2์ผ ์ „

CPP TIL

๋ชฉ๋ก ๋ณด๊ธฐ
6/7
post-thumbnail

๐Ÿ“… 2026-04-06
์ด๋ฒˆ์ฃผ ๋ถ€ํ„ฐ ์˜ค์ „์—๋Š” C++๊ณต๋ถ€ ์˜คํ›„์—๋Š” ์–ธ๋ฆฌ์–ผ ๋ฐ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ๊ณต๋ถ€ ํ•  ์˜ˆ์ •
ํ•ด๋‹น ๊ธ€์€ ์–ธ๋ฆฌ์–ผ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ TIL์— ๋งํฌ๋กœ ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค.

๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด๋†“์€ MyString class๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๋ช… ์ง„ํ–‰๋จ.

#include<iostream>

class MyString
{
    char* string_content;
    int string_length;
    
    int memory_capacity;
public:
    MyString(int capacity);
    
    MyString(const char* str);
    
    MyString(const MyString& str);
    
    ~MyString();
    
    int length() const;
    
};

MyString::MyString(int capacity)
{
    string_content = new char[capacity];
    string_length = 0;
    memory_capacity = capacity;
    
    std::cout << "Capacity: " << capacity << std::endl;
}


MyString::MyString(const char* str)
{
    string_length = 0;
    while ( str[string_length++])
    {
        
    }
    
    string_content = new char[string_length];
    memory_capacity = string_length;
    
    for (int i = 0; i != string_length; i++) string_content[i] = str[i];
}


MyString::MyString(const MyString& str)
{
    string_length = str.string_length;
    string_content = new char[string_length];
    
    for (int i = 0; i != string_length; i++) string_content[i] = str.string_content[i];
}

MyString::~MyString()
{
    delete[] string_content;
}

int MyString::length() const
{
    return string_length;
}

Explicit

int main()
{
	 // ์˜ˆ๋ฅผ๋“ค์–ด MyStringํƒ€์ž…์„ ์ธ์ž๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜ SomethingToDoString()์ด ์žˆ๋‹ค๋ฉด
    
    SomethingToDoString(MyString("abc")); // ๋™์ž‘O
    SomethingToDoString("abc"); //๋™์ž‘O
    
    // "abc" C++์ปดํŒŒ์ผ๋Ÿฌ๋Š” ์ด ๋ฌธ์ž์—ด "abc"๋ฅผ ์–ด๋–ป๊ฒŒํ•˜๋ฉด MyString์œผ๋กœ ๋ณ€ํ™˜ ํ•  ์ˆ˜ ์žˆ์„์ง€ ์ƒ๊ฐํ•จ. 
    // ๊ทธ๋ฆฌ๊ณ  MyString ์ƒ์„ฑ์ž ์ค‘์—์„œ๋Š” MyString(const char* str)๊ฐ€ ์žˆ์–ด์„œ ์•”์‹œ์  ๋ณ€ํ™˜(implicit conversion)์„ ํ•จ
    SomethingToDoString("abc") -> SomethingToDoString(MyString("abc"));
}

์ด๋Ÿฐ ์•”์‹œ์  ๋ณ€ํ™˜์„ ํ•˜์ง€ ์•Š๋„๋ก ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ๋ช…์‹œํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ํ‚ค์›Œ๋“œ๊ฐ€ explicit์ด๋‹ค.

์ฒ˜์Œ์— ์ž‘์„ฑํ•œ MyString ํด๋ž˜์Šค์—์„œ ์ˆ˜์ •์„ ํ•ด๋ณด์ž.

class MyString
{
    char* string_content;
    int string_length;
    
    int memory_capacity;
public:
    MyString(int capacity);
    
    explicit MyString(const char* str); // ์ˆ˜์ •
    
    MyString(const MyString& str);
    
    ~MyString();
    
    int length() const;
    
};

...

int main()
{
	SomethingToDoString("abc"); // ์ปดํŒŒ์ผ ์—๋Ÿฌ
}

๋˜ํ•œ explicit์€ ๋ณต์‚ฌ ์ƒ์„ฑ์ž ํ˜ธ์ถœ๋„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

MyString s("abc"); // ํ—ˆ์šฉ
MyString s = "abc"; // ์ปดํŒŒ์ผ ์—๋Ÿฌ

Mutable

#include <iostream>

class A
{
    int data_;
    
public:
    A(int data) : data_(data) {}
    void DoSomething(int x) const
    {
        data_ = x;
    }
    
    void PrintData() const
    {
        std::cout << data_ << std::endl;
    }
};
int main(int argc, char* argv[])
{
    A a(10);
    a.DoSomething(3);
    a.PrintData();
    return 0;
}

์œ„ ์ฝ”๋“œ๋Š” void DoSomething > data_ = x; ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

ํ•˜์ง€๋งŒ int data_๋ฅผ mutable๋กœ ์„ ์–ธํ•œ๋‹ค๋ฉด ์–ด๋–จ๊นŒ?

class A
{
    mutable int data_;
    
public:
    A(int data) : data_(data) {}
    void DoSomething(int x) const
    {
        data_ = x;
    }
    
    void PrintData() const
    {
        std::cout << data_ << std::endl;
    }
};
int main(int argc, char* argv[])
{
    A a(10);
    a.DoSomething(3);
    a.PrintData();
    return 0;
}

3์ด ์ž˜ ์ถœ๋ ฅ๋˜๋Š”๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๊ทธ๋Ÿผ ์ด๋Ÿฐ ์งˆ๋ฌธ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

mutable์„ ์“ธ๊ฑฐ๋ฉด ์ฐจ๋ผ๋ฆฌ DoSomething์—์„œ const๋ฅผ ๋นผ๋ฉด ๋˜์ง€ ์•Š๋‚˜?

mutable์„ ์™œ ์จ์•ผํ• ๊นŒ?

๋ฉค๋ฒ„ํ•จ์ˆ˜๋ฅผ ์™œ const๋กœ ์„ ์–ธํ•˜๋Š”์ง€ ๋จผ์ € ์ƒ๊ฐํ•ด๋ด์•ผํ•˜๋Š”๋ฐ
ํด๋ž˜์Šค ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋“ค์€ ์ด ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์–ด๋–ค ์ผ์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ  ์žˆ๋‹ค.

๋ฉค๋ฒ„ํ•จ์ˆ˜๋ฅผ const๋กœ ์„ ์–ธํ•˜๋Š” ์˜๋ฏธ๋Š”

์ด ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์ƒํƒœ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ ์ฝ๊ธฐ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋“ค์„ ๋“ค ์ˆ˜ ์žˆ๋‹ค.

class Server
{
    // ... ์ƒ๋žต ...
    
    Cache cache;
    
    User GetUserInfo(const int user_id) const
    {
        // ์บ์‹œ์—์„œ user_id ๊ฒ€์ƒ‰
        Data user_data = cache.find(user_id);
        
        // ๋งŒ์•ฝ ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์š”์ฒญ
        if (!user_data)
        {
            user_data = Database.find(user_id);
            
            // ์ดํ›„ ์บ์‹œ์— user_data ๋“ฑ๋ก
            cache.update(user_id, user_data); // ์ปดํŒŒ์ผ ์—๋Ÿฌ > const ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€์ˆ˜๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅ
        }
        
        // ๋ฆฌํ„ด๋œ ์ •๋ณด๋กœ User ๊ฐ์ฒด ์ƒ์„ฑ
        return User(user_data);
    }
};

GetUserInfo๊ฐ€ const ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์บ์‹œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

ํ•˜์ง€๋งŒ Cache๋ฅผ mutable๋กœ ์„ ์–ธํ•˜๊ฒŒ ๋˜๋ฉด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

profile
์ด๊ฒƒ ์ €๊ฒƒ ๋‹คํ•ด๋ณด๋Š” ์‚ถ

0๊ฐœ์˜ ๋Œ“๊ธ€