[Effective C++] 항목 26 : 변수 정의는 늦출 수 있는 데까지 늦추는 근성을 발휘하자

수민이슈·2023년 3월 28일
0

Effective C++

목록 보기
26/30
post-thumbnail

스콧 마이어스의 Effective C++을 읽고 개인 공부 목적으로 요약 작성한 글입니다!

💡 변수 정의는 늦출 수 있을 때까지 늦추자!
프로그램이 더 깔끔해지고, 효율도 좋아진다


🖊️ 변수 정의를 늦춰야 하는 이유

생성자와 소멸자 비용

생성자, 소멸자를 끌고다니는 타입으로 변수를 선언하면,

  • 프로그램 제어 흘므이 변수의 정의에 닿을 때 생성자가 호출되는 비용
  • 그 변수가 유효범위를 벗어날 때 소멸자가 호출되는 비용

이 반드시 소모된다.

변수가 정의되었으나 사용되지 않은 경우에도 이 비용을 지불해야 한다.

void encrypt(std::string& s);

std::string encryptPassword(const string::string& password) {
	...
    std::string encrypted;
    
    if ( ... ) {
    	throw logic_error(" ... ");
    }
    ...
    return encrypted;
}

이 경우에 에러가 발생해서 encrypted를 사용하지 않았는데도 생성자, 소멸자 호출 비용을 내야 한다.
개억울함..

그래서 변수를 사용할 때까지 미뤄야 한다.

근데,

void encrypt(std::string& s);

std::string encryptPassword(const string::string& password) {
	...
    std::string encrypted;
    encrypted = password;
    
    encrpyt(encrypyted);
    return encrypted;

이렇게 하면
encrypted에서 string의 기본 생성자가 불리고
그 이후에 대입한다

뭔가..
억울하고 비효율적이다

기본 생성자 말고 복사 생성자로

그냥 어차피 생성하고 값 대입해줄거면
대입할 값이 생길때까지 생성을 미뤘다가
복사 생성자로 생성해주자

void encrypt(std::string& s);

std::string encryptPassword(const string::string& password) {
	...
    std::string encrypted(password);
    
    encrpyt(encrypyted);
    return encrypted;

🖊️ 루프에서 변수 정의는 어떻게 할까?

A 방법

Widget w;
for (int i = 0 ; i < n ; ++i) {
	w = ...;
}

B 방법

for (int i = 0 ; i < n ; ++i) {
	Widget w = ...;
}

A vs B 비교

A : 생성자 1번 + 소멸자 1번 + 대입 n번
B : 생성자 n번 + 소멸자 n번

대입 비용이 생성자+소멸자의 비용보다 적은 경우는 A가 효율이 좋다.
근데 반대에는 B가 더 좋을거다.

그리고

A는 w의 유효범위가 B보다 넓어지기 때문에
프로그램의 이해도, 유지보수성이 떨어진다

그니까

"대입이 생성자-소멸자 쌍보다 비용이 덜 들고, 전체 코드에서 수행 성능에 민감한 부분을 건드리는 중"
이 아니라면,
B 방법으로 정의하자.


😊

프로그래머스에서 맨날 리턴값 선언해준 채로 나와서
그 방법에 살짝 익숙해질랑말랑 했는데
오우
항상 명심해야겠다
갱장히 쉬운 내용이지만
잊지말좡

0개의 댓글