https://github.com/MIN-JU-CHO/CppStudy/blob/main/13_2_Move.cpp

// 이동 생성자
MyString(MyString&& ref) noexcept
	{
		id = ++cnt;
		cout << id << " 이동 생성\\n";
		size = ref.size;
		length = ref.length;
		if (size < length)
		{
			size = length;
		}
		data = ref.data;
		ref.data = nullptr;
	}
// 이동 대입 연산자
MyString& operator=(MyString&& str) noexcept
	{
		cout << "이동\\n";
		delete[] data;
		size = str.size;
		length = str.length;
		if (size < length)
		{
			size = length;
		}
		data = str.data;
		str.data = nullptr;
		return (*this);
	}

Untitled

추측 이유:

size = str.size; length = str.length;

해당 객체가 더 이상 유효한 데이터를 가리키지 않도록 하는 역할?

참고했던 링크

https://ansohxxn.github.io/cpp/chapter15-3/

// 이동 생성자
MyString(MyString&& ref) noexcept
	{
		id = ++cnt;
		cout << id << " 이동 생성\\n";
		size = ref.size;
		length = ref.length;
		if (size < length)
		{
			size = length;
		}
		data = ref.data;
		ref.length = 0;
		ref.size = 0;
		ref.data = nullptr;
	}
// 이동 대입 연산자
MyString& operator=(MyString&& str) noexcept
	{
		cout << "이동\\n";
		delete[] data;
		size = str.size;
		length = str.length;
		if (size < length)
		{
			size = length;
		}
		data = str.data;
		str.length = 0;
		str.size = 0;
		str.data = nullptr;
		return (*this);
	}

Untitled

드디어 원인 찾음

Untitled

따라서 ref.length와 ref.size를 0으로 만들어줌으로써 복사(operator=(const&)) 시에 반드시 new 로 동적할당 해주게끔 (사이즈가 항상 작아서, if문 안으로 들어가게끔) 유도하게 하면 오류가 생기지 않는다.


#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;

size_t GetLen( string str)
{
	return str.size();
}

size_t GetLen(const char* str)
{
	return strlen(str);
}

template<typename String, typename... Strings>
size_t GetLen( String str, Strings... strs)
{
	return GetLen(str) + GetLen(strs...);
}

void Append(string* str)
{
	return;
}

template<typename String, typename... Strings>
void Append(string* origin,  String str, Strings... strs)
{
	origin->append(str);
	Append(origin, strs...);
}

template<typename String, typename... Strings>
string StrConcat( String str, Strings... strs)
{
	size_t length = GetLen(str, strs...);
	cout << "Length: " << length << "\\n";
	string result;
	result.resize(length);
	result = str;
	Append(&result, strs...);
	return result;
}

int main(void)
{
	string word = "this";
	cout << StrConcat(word, " ", "is", " ", "a", " ", "sentence", "\\n");
}
#include <string>
#include <iostream>
#include <stdlib.h>
using namespace std;

size_t GetLen(const string& str)
{
	return str.size();
}

size_t GetLen(const char* str)
{
	return strlen(str);
}

template<typename String, typename... Strings>
size_t GetLen(const String& str, Strings... strs)
{
	return GetLen(str) + GetLen(strs...);
}

void Append(string* str)
{
	return;
}

template<typename String, typename... Strings>
void Append(string* origin, const String& str, Strings... strs)
{
	origin->append(str);
	Append(origin, strs...);
}

template<typename String, typename... Strings>
string StrConcat(const String& str, Strings... strs)
{
	size_t length = GetLen(str, strs...);
	cout << "Length: " << length << "\\n";
	string result;
	result.resize(length);
	result = str;
	Append(&result, strs...);
	return result;
}

int main(void)
{
	string word = "this";
	cout << StrConcat(word, " ", "is", " ", "a", " ", "sentence", "\\n");
}

첫번째 인자를 const String &로 해도 되고, String으로 해도 되는, 둘 다 정상적(좌측값, 우측값)으로 실행되는 이유가 뭘까?

const string &와 const char * 두 타입을 모두 아우를 수 있기 때문이라고 생각했는데,, 더 구체적이고도 논리적인 이유가 필요하다.