#include <iostream>
#include <set>
using namespace std;
class StudentT {
public:
int id;
string name;
public:
StudentT(int _id, string _name) : id(_id), name(_name) {
}
int getId() {
return id;
}
string getName() {
return name;
}
};
inline bool operator< (StudentT s1, StudentT s2) {
return s1.getId() < s2.getId();
}
int main() {
set<StudentT> st;
StudentT s1(0, "Tom");
StudentT s2(1, "Tim");
st.insert(s1);
st.insert(s2);
set<StudentT> :: iterator itr;
for (itr = st.begin(); itr != st.end(); itr++) {
cout << itr->getId() << " " << itr->getName() << endl;
}
return 0;
}
Di barisan:
cout << itr->getId() << " " << itr->getName() << endl;
Ini memberikan kesalahan bahwa:
../main.cpp:35: error: meneruskan 'const StudentT' sebagai argumen 'this' dari 'int StudentT :: getId ()' membuang kualifikasi
../main.cpp:35: error: meneruskan 'const StudentT' sebagai argumen 'this' dari 'std :: string StudentT :: getName ()' membuang kualifikasi
Apa yang salah dengan kode ini? Terima kasih!
volatile
Jawaban:
Objek dalam
std::set
disimpan sebagaiconst StudentT
. Jadi, ketika Anda mencoba untuk memanggilgetId()
denganconst
obyek compiler mendeteksi masalah, terutama Anda menelepon non-const fungsi anggota pada objek const yang tidak diperbolehkan karena non-const fungsi anggota membuat NO PROMISE untuk tidak memodifikasi objek; jadi kompiler akan membuat asumsi yang aman yanggetId()
mungkin mencoba untuk memodifikasi objek tetapi pada saat yang sama, ia juga memperhatikan bahwa objek tersebut adalah const; jadi setiap upaya untuk memodifikasi objek const harus menjadi kesalahan. Karenanya kompiler menghasilkan pesan kesalahan.Solusinya sederhana: buat fungsi const sebagai:
Ini diperlukan karena sekarang Anda dapat memanggil
getId()
dangetName()
objek const sebagai:Sebagai sidenote, Anda harus menerapkan
operator<
sebagai:Parameter note sekarang
const
referensi.sumber
const StudentT & s1, const StudentT & s2
?const
karena fungsi tidak perlu memodifikasi objek, jadiconst
ini memberlakukan ini pada waktu kompilasi.Fungsi anggota yang tidak memodifikasi instance kelas harus dinyatakan sebagai
const
:Setiap kali Anda melihat "membuang kualifikasi", itu berbicara tentang
const
atauvolatile
.sumber
const
datangnya dari sini, tapi saya curigaset
mengembalikan referensi const dari iterator untuk mencegah instance berubah dan dengan demikian membatalkan set.foo obj;
menjadiconst foo obj;
sekali dan lihat apa yang terjadi. Atau berikanconst
referensi ke afoo
.set
diubah, urutannya bisa kesal dan set tidak lagi valid. Dalam amap
, hanya kuncinyaconst
. Dalam aset
, seluruh objek adalah kuncinya.f()
dalam jawaban saya.Sebenarnya standar C ++ (yaitu konsep C ++ 0x ) mengatakan (tnx ke @Xeo & @Ben Voigt untuk menunjukkan hal itu kepada saya):
Jadi implementasi Dinkumware VC ++ 2008 salah.
Jawaban lama:
Anda mendapatkan kesalahan itu karena dalam implementasi tertentu dari std lib
set::iterator
sama denganset::const_iterator
.Misalnya libstdc ++ (dikirimkan bersama g ++) memilikinya (lihat di sini untuk seluruh kode sumber):
Dan dalam dokumen SGI disebutkan:
Di sisi lain VC ++ 2008 Express mengkompilasi kode Anda tanpa mengeluh bahwa Anda memanggil metode non const pada
set::iterator
s.sumber
Mari saya beri contoh yang lebih detail. Adapun struct di bawah ini:
Seperti yang Anda lihat di atas, IDE (CLion), akan memberikan tips
Non-const function 'getCount' is called on the const object
. Dalam metodeadd
count
ini dinyatakan sebagai objek const, tetapi metodegetCount
ini bukan metode const, jadicount.getCount()
dapat mengubah anggota dalamcount
.Kompilasi kesalahan seperti di bawah ini (pesan inti di kompiler saya):
Untuk mengatasi masalah di atas, Anda dapat:
uint32_t getCount(){...}
menjadiuint32_t getCount() const {...}
. Jadicount.getCount()
tidak akan mengubah anggotacount
.atau
uint32_t add(const Count& count){...}
keuint32_t add(Count& count){...}
. Jadi,count
jangan pedulikan mengubah anggota di dalamnya.Mengenai masalah Anda, objek di std :: set disimpan sebagai const StudentT, tetapi metode
getId
dangetName
bukan const, jadi Anda memberikan kesalahan di atas.Anda juga dapat melihat pertanyaan ini Arti dari 'const' terakhir dalam deklarasi fungsi suatu kelas? untuk lebih detail.
sumber