새로운 직업에서, 나는 다음과 같은 코드에 대한 코드 리뷰에 플래그를 붙였습니다.
PowerManager::PowerManager(IMsgSender* msgSender)
: msgSender_(msgSender) { }
void PowerManager::SignalShutdown()
{
msgSender_->sendMsg("shutdown()");
}
마지막 방법은 다음과 같아야한다고 들었습니다.
void PowerManager::SignalShutdown()
{
if (msgSender_) {
msgSender_->sendMsg("shutdown()");
}
}
즉, 내가 해야한다 풋 NULL
주위에 가드 msgSender_
가 개인 데이터 멤버 인 경우에도 변수입니다. 내가이 '지혜'에 대해 어떻게 느끼는지 설명하기 위해 expletives를 사용하는 것을 자제하는 것은 어렵다. 설명을 요청하면 몇 년 동안 일부 주니어 프로그래머가 클래스가 어떻게 작동해야하는지에 대해 혼란스러워하고 자신이 없어야 할 멤버를 실수로 삭제 한 NULL
후 (그리고 나중에 설정해야 함) 무서운 이야기를 얻습니다. 제품 출시 직후 현장에서 문제가 발생했으며 모든 것을NULL
확인하는 것이 더 낫다는 "어려운 방법을 배우고 우리를 믿습니다" .
나에게 이것은 화물 컬트 프로그래밍 처럼 느껴지고 단순하고 단순합니다. 선의의 동료 몇 명이 저에게 '얻기'를 돕고 이것이 더 강력한 코드를 작성하는 데 어떻게 도움이되는지 알아 보려고 노력하고 있습니다. 그러나 나는 그들이 그것을 얻지 못하는 사람이라는 느낌을 줄 수 없습니다. .
코딩 표준 에서 함수에서 역 참조 된 모든 단일 포인터가 NULL
개인 데이터 멤버까지도 먼저 확인 하도록 요구하는 것이 합리적 입니까? (참고 : 상황을 설명하기 위해 항공 교통 관제 시스템이나 기타 '실패-사람-사람'제품이 아닌 가전 제품을 만듭니다.)
편집 : 위의 예에서 msgSender_
공동 작업자는 선택 사항이 아닙니다. 항상 NULL
이면 버그를 나타냅니다. 생성자로 전달되는 유일한 이유 PowerManager
는 모의 IMsgSender
서브 클래스 로 테스트 할 수 있기 때문 입니다.
요약 :이 질문에 정말 좋은 답변이있었습니다. 모두 감사합니다. 나는 @aaronps에서 주로 간결함으로 인해 하나를 수락했습니다. 다음과 같은 상당히 일반적인 계약이있는 것 같습니다.
- 의무화
NULL
에 대한 경비를 매 역 참조 포인터 것은 과잉이지만, - 참조 (가능한 경우) 또는
const
포인터 를 사용하여 전체 토론을 회피 할 수 있습니다. assert
명령문은NULL
기능의 전제 조건이 충족되는지 확인하기 위해 경비원에 대한 보다 계몽 된 대안 입니다.
null
하고 아무것도하지 않는 것은 버그를 실행 아래로 옮기는 방법 일 뿐이므로 소스로 다시 추적하기가 훨씬 어렵습니다.