Info
알던 내용이긴 한데, 헷갈려서 정리하는겸 생성자가 호출되는 시기와 operator가 호출되는 시기에 대한 글을 써보려한다.
바로 예제를 먼저 확인해보자.
#include <cstdio>
template<unsigned N>
struct StaticString {
// ctor from C‑string
StaticString(const char* s) {
printf("→ StaticString(const char*) ctor\n");
// … copy into _data …
}
// default ctor
StaticString() {
printf("→ StaticString() default ctor\n");
}
// copy ctor
StaticString(const StaticString& o) {
printf("→ StaticString(const StaticString&) copy ctor\n");
}
// assignment from C‑string
StaticString& operator=(const char* s) {
printf("→ operator=(const char*)\n");
return *this;
}
// copy‑assignment
StaticString& operator=(const StaticString& o) {
printf("→ operator=(const StaticString&)\n");
return *this;
}
};
int main() {
puts("1) StaticString<8> a = \"abc\";");
StaticString<8> a = "abc";
// Output: → StaticString(const char*) ctor
puts("\n2) StaticString<8> b; b = \"xyz\";");
StaticString<8> b;
b = "xyz";
// Output:
// → StaticString() default ctor
// → operator=(const char*)
puts("\n3) StaticString<8> c = a;");
StaticString<8> c = a;
// Output: → StaticString(const StaticString&) copy ctor
puts("\n4) StaticString<8> d; d = a;");
StaticString<8> d;
d = a;
// Output:
// → StaticString() default ctor
// → operator=(const StaticString&)
return 0;
}예시로 구분할 수 있듯이, 생성과 동시에 할당을 진행하는 경우에는 생성자로 취급되며, 이후의 사용되는 operator의 경우에는 그것에 맞는 호출을 가지게 된다.
내가 헷갈린 부분에 대해서 짚어보겠다.
예시의 4번 연산과 같이 진행될 경우 operator=과 StaticString(…)가 연속적으로 호출되어 비효율적으로 동작하는게 아닐까 했는데.
operator=에서 참조를 반환하는 이유는 연속 호출(method chaining)을 구현하기 위한이지 반환하여 재할당하는 의도가 아니라는 것을 망각했다.
4번에서 d = a의 호출은 d.operator=(a)와 같다는 것을 기억하자.