const 반환의 의미

2019. 8. 22. 23:33PL/C++

#include <cstring>
#include <iostream>

using namespace std;

class Sample {
private:
	char *str;

public:
	Sample() {
		str = new char[255];
		strcpy(str, "1234");
	};
	~Sample() {
		delete[] str;
	}
	char *getString() {
		return str;
	}
};

int main(void) {
	char *tmp = new char[255];
	Sample *s = new Sample();

	tmp = s->getString();
	strcpy(tmp, "abcd");
	cout << s->getString() << '\n';
	delete tmp;
	return 0;
}

 

위 코드는 클래스 객체의 문자열 변수를 받아서 임의로 다른 내용으로 변환하는 내용이다. 좀 더 생각을 해보면 str은 private 선언으로 되어있으면, 바꿀 수 있는 멤버함수도 없다. 따라서 클래스 밖에서 str을 바꾸는 행위는 허용되면 안된다. 따라서 const 선언으로 이를 막을 수 있다

 

#include <cstring>
#include <iostream>

using namespace std;

class Sample {
private:
	char *str;

public:
	Sample() {
		str = new char[255];
		strcpy(str, "1234");
	};
	~Sample() {
		delete[] str;
	}
	const char *getString() {
		return str;
	}
};

int main(void) {
	char *tmp = new char[255];
	Sample *s = new Sample();

	// tmp = s->getString(); // 컴파일 오류
	strcpy(tmp, s->getString());
	cout << s->getString() << '\n';
	delete tmp;
	return 0;
}

 

const 선언을 하면 주소값을 받아오지는 못하지만, strcpy로 문자열을 복사하는 것까지는 가능하게 된다

 

다만, 취약점은 s->getString의 반환값을 (char *)로 타입 캐스팅하면 주소값을 얻을 수 있다는 것이다. 따라서 또 다시 위의 문제가 발생하게 된다

 

#include <cstring>
#include <iostream>

using namespace std;

class Sample {
private:
	char *str;

public:
	Sample() {
		str = new char[255];
		strcpy(str, "1234");
	};
	~Sample() {
		delete[] str;
	}
	const char *getString() {
		return str;
	}
};

int main(void) {
	char *tmp = new char[255];
	Sample *s = new Sample();

	tmp = (char *)s->getString();
	strcpy(tmp, "abcd");
	cout << s->getString() << '\n';
	
	delete tmp;
	return 0;
}

 

참조 연산자도 마찬가지로, 클래스의 private 멤버 변수 혹은 객체를 반환하는 모든 멤버 함수는 반드시 const 반환을 가져야만 한다

 

#include <cstring>
#include <iostream>

using namespace std;

class Sample {
private:
	char *str;

public:
	Sample() {
		str = new char[255];
		strcpy(str, "1234");
	};
	~Sample() {
		delete[] str;
	}
	char *getString() {
		return str;
	}
};

int main(void) {
	Sample *s = new Sample();

	char* &&tmp = s->getString();
	strcpy(tmp, "abcd");
	cout << s->getString() << '\n';
	delete tmp;
	return 0;
}

 

'PL > C++' 카테고리의 다른 글

const 정리  (0) 2019.08.23
Lvalue와 Rvalue  (0) 2019.08.23
Default 멤버 함수  (0) 2019.08.22
explicit를 사용해서 묵시적 변환을 허용하지 않는 이유  (0) 2019.08.22
전위연산자와 후위연산자의 연산자 오버로딩  (0) 2019.08.22