Mencoba mengumpulkan beberapa kegunaan:
Mengikat beberapa sementara ke referensi-ke-const, untuk memperpanjang masa pakainya. Referensi dapat berupa basis - dan destruktor tidak perlu virtual - destruktor yang tepat masih disebut:
ScopeGuard const& guard = MakeGuard(&cleanUpFunction);
Penjelasan , menggunakan kode:
struct ScopeGuard {
~ScopeGuard() { } // not virtual
};
template<typename T> struct Derived : ScopeGuard {
T t;
Derived(T t):t(t) { }
~Derived() {
t(); // call function
}
};
template<typename T> Derived<T> MakeGuard(T t) { return Derived<T>(t); }
Trik ini digunakan dalam kelas utilitas ScopeGuard milik Alexandrescu. Setelah sementara keluar dari ruang lingkup, destructor Derived dipanggil dengan benar. Kode di atas melewatkan beberapa detail kecil, tapi itulah masalahnya.
Gunakan const untuk memberi tahu orang lain bahwa metode tidak akan mengubah keadaan logis objek ini.
struct SmartPtr {
int getCopies() const { return mCopiesMade; }
};
Gunakan const untuk kelas copy-on-write , untuk membuat kompiler membantu Anda memutuskan kapan dan kapan Anda perlu menyalin.
struct MyString {
char * getData() { /* copy: caller might write */ return mData; }
char const* getData() const { return mData; }
};
Penjelasan : Anda mungkin ingin berbagi data saat Anda menyalin sesuatu selama data dari objek asli dan copie akan tetap sama. Setelah salah satu objek mengubah data, Anda perlu dua versi sekarang: Satu untuk yang asli, dan satu untuk salinan. Artinya, Anda menyalin pada tulisan ke objek mana pun, sehingga mereka sekarang memiliki versi sendiri.
Menggunakan kode :
int main() {
string const a = "1234";
string const b = a;
// outputs the same address for COW strings
cout << (void*)&a[0] << ", " << (void*)&b[0];
}
Cuplikan di atas mencetak alamat yang sama pada GCC saya, karena pustaka C ++ yang digunakan mengimplementasikan copy-on-write std::string
. Kedua string, meskipun mereka adalah objek yang berbeda, berbagi memori yang sama untuk data string mereka. Membuat b
non-const akan lebih memilih versi non-const dari operator[]
dan GCC akan membuat salinan buffer memori backing, karena kita bisa mengubahnya dan itu tidak akan mempengaruhi data a
!
int main() {
string const a = "1234";
string b = a;
// outputs different addresses!
cout << (void*)&a[0] << ", " << (void*)&b[0];
}
Untuk copy-constructor untuk membuat salinan dari objek const dan temporaries :
struct MyClass {
MyClass(MyClass const& that) { /* make copy of that */ }
};
Untuk membuat konstanta yang sepele tidak bisa berubah
double const PI = 3.1415;
Untuk melewati objek yang arbitrer dengan referensi alih-alih berdasarkan nilai - untuk mencegah kemungkinan by-value passing yang mahal atau tidak mungkin
void PrintIt(Object const& obj) {
// ...
}