// test.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
/*
변수 정의는 늦출 수 있는 데 까지!
생성자, 소멸자를 끌고 다니는 타입은 변수를 정의 하면 반드시 2가지의
비용이 든다.
1. 프로그램 제어 흐름이 변수의 정의에 닿을 때 생성자 호출
2. 유효범위를 벗어날 때 소멸자가 호출되는 비용.
*/
std::string encryptPassword_1(const std::string& password)
{
/*
encryptPassword_1
아래와 같이 string encrypted를 정의 했을 경우,
encrypted의 생성자, 소멸자를 반드시 실행 하게 된다.
하지만 예외가 발생 할 경우,
encrypted는 사용 되지 않지만, encrypted의 생성자, 소멸자
비용은 똑같이 든다.
*/
std::string encrypted;
/// 예외 처리 소스...
/// 주어진 비밀번호를 암호화 하여 encrypted에 대입.
return encrypted;
}
std::string encryptPassword_2(const std::string& password)
{
/*
encryptPassword_2
아래와 같이 변경했을 경우, 예외가 발생할 경우
encrypted의 생성자 소멸자 비용은 들지 않지만
예외가 발생 하지 않을 경우는
encrypted의 기본 생성자를 호출하게 되고 대입 연산을 호출 하게 된다.
*/
/// 예외 처리 소스...
std::string encrypted;
/// 주어진 비밀번호를 암호화 하여 encrypted에 대입.
return encrypted;
}
void encrypt(std::string& password)
{
/// 암호화한다.
}
std::string encryptPassword_3(const std::string& password)
{
/*
encryptPassword_3
std::string encrypted의 기본 생성자의 불필요한 비용을 예방 할수 있고,
예외가 발생 해도 사용하지 않는
std::string encrypted의 생성자를 호출 하지 않는다.
*/
/// 예외 처리 소스...
std::string encrypted(password);
encrypt(encrypted);
return encrypted;
}
/*
결론 : 변수의 정의를 늦추는 것은 기본이고,
초기화 인자를 손에 넣기 전까지 정의를 늦출수 있는지도 둘러봐야 한다.
*/
class CWidget
{
private:
int m_index;
public:
CWidget()
: m_index(0)
{
std::cout << "생성자 호출" << std::endl;
}
explicit CWidget(const int index)
: m_index(index)
{
std::cout<< "생성자 호출" << std::endl;
}
~CWidget()
{
std::cout<< "소멸자 호출" << std::endl;
}
void SetIndex(const int index)
{
m_index = index;
std::cout<< "대입 호출" << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
/*
방법 A : 루프 바깥쪽에 정의
생성자 1번 + 소멸자 1번 + 대입 n번
*/
{
std::cout <<"루프 바깥쪽에 정의" << std::endl;
CWidget w;
for(int i=0; i<10/*n*/; ++i)
{
w.SetIndex(i);
}
}
/*
방법 B : 루프 안쪽에 정의
생성자 n번 + 소멸자 n번
*/
std::cout << "루프 안쪽 정의" << std::endl;
for(int i=0; i<10/*n*/; ++i)
{
CWidget w(i);
}
return 0;
/*
대입에 들어가는 비용이 생성자 소멸자쌍보다 적게 나오는 경우는
A방법이 일반적으로 훨씬 효율이 좋음.
대입이 생성자 소멸자 쌍보다 비용이 덜 들고,
전체 코드에서 수행 성능에 민감한 부분을 건드리는중이라고
생각히자 않는다면, B방법이 좋음.
*/
}