[Effective C++] #26_변수 정의
Scott Meyers의 "Effective C++" 를 통해, C++ 구현에 필요한 개념들을 이해하고, 기록하기 위함입니다. 항목은 5장 '구현', 항목 26 "변수 정의는 늦출 수 있는 데까지 늦추는 근성을 발휘"에 해당하는 내용입니다.
변수 정의
변수를 정의하면 항상 부담해야 하는 비용이 두 가지가 있습니다. 하나는 프로그램 제어 흐름이 변수의 정의에 닿을 때 생성자가 호출되는 비용, 또 하나는 변수가 유효범위를 벗어날 때 소멸자가 호출되는 비용입니다.
변수를 일찍 정의 했을 때
std::string encryptPassword(const std::string& password){
using namespace std;
string encryptedPassword;
if(password.length() < MinPasswordLength){ // 패스워드가 너무 짧으면 예외 발생!
throw logic_error("Password is too short!");
}
... // 암호화 진행
return encryptedPassword
}
비밀번호를 암호화하는 "encryptPassword"함수 예제입니다. 이 함수는 주어진 비밀번호가 너무 짧으면 logic_error타입의 예외를 던지도록 설계되어 있습니다. "encryptedPassword" 객체가 아예 안쓰인다고 볼 수 없지만, 이 함수가 예외를 던지면사용하지 않을 "encryptedPassword" 객체의 생성과 소멸에 대해 비용을 내야 하겠죠? 따라서, 우리는 위 코드를 수정해보도록 합니다. 최대한 정의를 늦추는거죠
변수 생성 후 대입
std::string encryptPassword(const std::string& password){
...
std::string encryptedPassword; // 최대한 정의를 늦추고
encrytpedPassword = password; // 대입 연산
encrypt(encryptedPassword);
return encryptedPassword;
}
"encryptedPassword" 객체의 생성을 최대한 늦췄지만, 문제점이 한개 또 존재합니다. 객체를 기본 생성하고나서 값을 대입하는 방법보다, 우리는 객체를 원하는 값으로 직접 초기화 하는 방법이 좋다는것을 알고 있습니다. 의미없는 기본 생성자 호출을 생략하고 아래 코드로 넘어거가겠습니다.
직접 초기화
std::string encryptPassword(const std::string& password){
...
std::string encryptedPassword = encrypt(password);
return encryptedPassword;
}
루프 안에 변수를 정의? 루프 밖에 변수를 정의?
// 1. 루프 안에 정의
for(int i=0; i<n; i++){
A a(i);
...
}
// 2. 루프 밖에 정의
A a;
for (int i=0; i<n i++){
a = i;
}
2번 방법이 효율적인 경우는 클래스 중 "대입"에 들어가는 비용이 생성자+소멸자 비용보다 적게 나오는 경우입니다. 반면에 1번 방법은 대입이 생성자+소멸자 비용보다 적고, 전체 코드에서 수행성능에 민감한 부분을 건드리는 경우입니다.
변수 정의는 늦출 수 있을 때까지 늦춥시다. 프로그램이 더 깔끔해지며 효율도 좋아집니다.
'언어 > Effective C++' 카테고리의 다른 글
[Effective C++] #30_인라인 함수 (0) | 2021.12.30 |
---|---|
[Effective C++] #29_예외 안전성 확보 (0) | 2021.12.28 |
[Effective C++] #28_내부에서 사용하는 객체에 대한 핸들 반환 (0) | 2021.12.28 |
[Effective C++] #27_캐스팅 (0) | 2021.12.27 |
[Effective C++] #25_예외를 던지지 않는 swap에대한 지원 (0) | 2021.12.25 |