Ở một công việc mới, tôi đã bị đánh dấu trong các đánh giá mã cho mã như thế này:
PowerManager::PowerManager(IMsgSender* msgSender)
: msgSender_(msgSender) { }
void PowerManager::SignalShutdown()
{
msgSender_->sendMsg("shutdown()");
}
Tôi đã nói rằng phương pháp cuối cùng nên đọc:
void PowerManager::SignalShutdown()
{
if (msgSender_) {
msgSender_->sendMsg("shutdown()");
}
}
tức là, tôi phải đặt một NULL
người bảo vệ xung quanh msgSender_
biến, mặc dù đó là một thành viên dữ liệu riêng tư. Thật khó cho tôi để kiềm chế bản thân khỏi việc sử dụng thám hiểm để mô tả cảm giác của tôi về phần 'trí tuệ' này. Khi tôi yêu cầu một lời giải thích, tôi nhận được một loạt các câu chuyện kinh dị về cách một số lập trình viên cơ sở, một số năm, đã bối rối về cách một lớp học phải làm việc và vô tình xóa một thành viên mà anh ta không nên có (và đặt nó NULL
sau đó , rõ ràng), và mọi thứ đã nổ tung trên cánh đồng ngay sau khi phát hành sản phẩm và chúng tôi đã "học một cách khó khăn, tin tưởng chúng tôi" rằng tốt hơn là chỉ cần NULL
kiểm tra mọi thứ .
Đối với tôi, điều này cảm thấy giống như lập trình sùng bái hàng hóa , đơn giản và đơn giản. Một vài đồng nghiệp tốt bụng đang cố gắng giúp tôi 'lấy nó' và xem điều này sẽ giúp tôi viết mã mạnh mẽ hơn như thế nào, nhưng ... tôi không thể cảm thấy như họ là những người không hiểu được .
Có hợp lý không khi một tiêu chuẩn mã hóa yêu cầu mọi con trỏ đơn lẻ được kiểm duyệt trong một hàm phải được kiểm tra cho NULL
các thành viên dữ liệu riêng tư đầu tiên ngay cả? (Lưu ý: Để đưa ra một số bối cảnh, chúng tôi tạo ra một thiết bị điện tử tiêu dùng, không phải là hệ thống kiểm soát không lưu hoặc một số sản phẩm 'thất bại tương đương với người chết'.)
EDIT : Trong ví dụ trên, msgSender_
cộng tác viên không phải là tùy chọn. Nếu nó đã từng NULL
, nó chỉ ra một lỗi. Lý do duy nhất nó được truyền vào hàm tạo là PowerManager
có thể được kiểm tra với một IMsgSender
lớp con giả .
TÓM TẮT : Có một số câu trả lời thực sự tuyệt vời cho câu hỏi này, cảm ơn tất cả mọi người. Tôi đã chấp nhận một từ @aaronps chủ yếu do tính ngắn gọn của nó. Dường như có một thỏa thuận chung khá rộng rằng:
- Bảo
NULL
vệ bắt buộc cho mọi con trỏ bị hủy bỏ đơn lẻ là quá mức cần thiết, nhưng - Bạn có thể bước bên cạnh toàn bộ cuộc tranh luận bằng cách sử dụng một tham chiếu thay thế (nếu có thể) hoặc một
const
con trỏ và assert
báo cáo là một thay thế được khai sáng hơn cho cácNULL
vệ sĩ để xác minh rằng các điều kiện tiên quyết của chức năng được đáp ứng.
null
và không làm gì chỉ là một cách để di chuyển lỗi xuống thực thi, khiến việc theo dõi lại nguồn trở nên khó khăn hơn nhiều.