๐
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;
}
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"; // ์ปดํ์ผ ์๋ฌ

#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๋ก ์ ์ธํ๊ฒ ๋๋ฉด ์์ ํ ์ ์๊ฒ ๋๋ค.