Khai báo const giúp tăng tính an toàn và rõ ràng cho mã nguồn. Có ba vị trí chính cần áp dụng:
char message[] = "XinChao";
char* const ptrConst = message; // Con trỏ hằng
const char* dataConst = message; // Dữ liệu hằng
char const* dataConstAlt = message; // Cách viết thay thế
char* ptrNormal = message; // Không hằng
const char* const fullConst = message; // Cả hai đều hằng
Đối với iterator trong STL, cần phân biệt rõ:
void minh_hoa_dieu_kien() {
std::vector<std::string> danhSach(1, "C++");
const auto itFix = danhSach.begin();
*itFix = "Modern C++";
// ++itFix; // Lỗi: không thể thay đổi vị trí
auto itChiDoc = danhSach.cbegin();
// *itChiDoc = "Lỗi"; // Dữ liệu không thể sửa
++itChiDoc;
}
Trả về giá trị hằng từ hàm toán tử ngăn ngừa thao tác không hợp lệ:
class PhanSo {
public:
PhanSo() = default;
};
const PhanSo operator+(const PhanSo& trai, const PhanSo& phai) {
return PhanSo();
}
void kiem_thu_toan_tu() {
PhanSo x, y, z;
x = y + z;
// y + z = x; // Lỗi biên dịch do giá trị trả về là hằng
}
Phương thức hằng cho phép xử lý đối tượng const và hỗ trợ nạp chồng:
class KhoiVanBan {
public:
KhoiVanBan(const std::string& noiDung) : noiDung(noiDung) {}
char& operator[](size_t viTri) {
std::cout << "Bản thường ";
return noiDung[viTri];
}
const char& operator[](size_t viTri) const {
std::cout << "Bản hằng ";
return noiDung[viTri];
}
private:
std::string noiDung;
};
Từ khóa mutable cho phép sửa đổi trường dữ liệu trong phương thức hằng:
class KhoiVanBanNangCao {
public:
KhoiVanBanNangCao(const std::string& s) : chuoi(s) {}
size_t tinhDoDai() const {
if (!daTinh) {
doDai = chuoi.length();
daTinh = true;
}
return doDai;
}
private:
std::string chuoi;
mutable size_t doDai;
mutable bool daTinh = false;
};
Tránh lặp code bằng cách chuyển hướng từ phương thức không hằng sang hằng:
class KhoiVanBanThongMinh {
public:
char& operator[](size_t idx) {
return const_cast<char&>(
static_cast<const KhoiVanBanThongMinh&>(*this)[idx]
);
}
const char& operator[](size_t idx) const {
return noiDung[idx];
}
private:
std::string noiDung;
};