const 반환의 의미
2019. 8. 22. 23:33ㆍPL/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 |