Saya memiliki kelas dengan private char str[256];
dan untuk itu saya memiliki konstruktor eksplisit:
explicit myClass(const char *func)
{
strcpy(str,func);
}
Saya menyebutnya sebagai:
myClass obj("example");
Ketika saya mengkompilasi ini saya mendapatkan peringatan berikut:
konversi usang dari konstanta string ke 'char *'
Mengapa ini terjadi?
c++
string
explicit-constructor
mkamthan
sumber
sumber
strncpy(str, func, 255)
alih-alihstrcpy(str, func)
untuk salinan yang lebih aman. Dan jangan lupa untuk menambahkan '\ 0' di akhir string karena strncpy tidak menambahkannya.Jawaban:
Ini adalah pesan kesalahan yang Anda lihat setiap kali Anda memiliki situasi seperti berikut:
Mengapa? Nah, C dan C ++ berbeda dalam jenis string literal. Dalam C jenisnya adalah array char dan dalam C ++ itu adalah array konstan char. Dalam kasus apa pun, Anda tidak diperbolehkan untuk mengubah karakter string literal, sehingga const di C ++ sebenarnya bukan batasan tetapi lebih merupakan jenis keamanan. Konversi dari
const char*
kechar*
umumnya tidak mungkin dilakukan tanpa pemeran eksplisit untuk alasan keamanan. Tetapi untuk kompatibilitas mundur dengan C bahasa C ++ masih memungkinkan menetapkan string literal ke achar*
dan memberi Anda peringatan tentang konversi ini menjadi usang.Jadi, di suatu tempat Anda kehilangan satu atau lebih
const
dalam program Anda untuk kebenaran const. Tetapi kode yang Anda tunjukkan kepada kami bukanlah masalah karena tidak melakukan konversi yang sudah usang ini. Peringatan itu pasti datang dari tempat lain.sumber
const
dariMyClass
konstruktor ... lalu Anda dapat memperbaikinya dengan menambahkanconst
kembali.Peringatan:
diberikan karena Anda melakukan sesuatu (bukan dalam kode yang Anda posting) sesuatu seperti:
Masalahnya adalah bahwa Anda mencoba untuk mengubah string literal (dengan tipe
const char[]
) menjadichar*
.Anda dapat mengkonversi
const char[]
keconst char*
karena array meluruh ke pointer, tetapi apa yang Anda lakukan adalah membuat sebuah konstanta bisa berubah.Konversi ini mungkin diizinkan untuk kompatibilitas C dan hanya memberi Anda peringatan yang disebutkan.
sumber
Sebagai jawaban tidak. 2 oleh fnieto - Fernando Nieto dengan jelas dan benar menjelaskan bahwa peringatan ini diberikan karena di suatu tempat dalam kode Anda yang Anda lakukan (bukan dalam kode yang Anda posting) sesuatu seperti:
Namun, jika Anda juga ingin menjaga kode Anda bebas dari peringatan maka cukup lakukan perubahan pada kode Anda:
Artinya, cukup masukkan
string
konstanta ke(char *)
.sumber
void foo(char* str)
seperti ini? Saya pikir kita tidak bisa moditystr
dalam cara apafoo
pun, bahkan parameter ditulis sebagai non-const.Ada 3 solusi:
Solusi 1:
Solusi 2:
Solusi 3:
Array juga dapat digunakan sebagai ganti pointer karena array sudah menjadi pointer konstan.
sumber
strdup
. Tidak seperti kode Anda, itu akan mengalokasikan ruang untuk karakter NUL terminating, dan tidak membanjiri alokasi.Sebenarnya string konstanta literal bukanlah const char * atau char * tetapi char []. Cukup aneh tapi ditulis dalam spesifikasi c ++; Jika Anda memodifikasinya perilaku tidak terdefinisi karena kompiler dapat menyimpannya di segmen kode.
sumber
Mungkin Anda bisa mencoba ini:
Ini bekerja untuk saya
sumber
Saya mengatasi masalah ini dengan menambahkan makro ini di awal kode, di suatu tempat. Atau tambahkan
<iostream>
, hehe.sumber
C_TEXT
tidak masalah untuk pemanggilan fungsi (foo(C_TEXT("foo"));
), tetapi menyerukan perilaku tidak terdefinisi jika nilai disimpan dalam variabel sepertichar *x = C_TEXT("foo");
- setiap penggunaanx
(selain dari penugasan) adalah perilaku tidak terdefinisi karena memori yang ditunjuknya telah dibebaskan.Alasan untuk masalah ini (yang bahkan lebih sulit untuk dideteksi daripada masalah dengan
char* str = "some string"
- yang orang lain telah jelaskan) adalah ketika Anda menggunakanconstexpr
.Tampaknya itu akan berperilaku mirip dengan
const char* str
, dan karenanya tidak akan menyebabkan peringatan, seperti yang terjadi sebelumnyachar*
, tetapi sebaliknya berperilaku sebagaichar* const str
.Detail
Pointer konstan, dan pointer ke konstanta. Perbedaannya antara
const char* str
, danchar* const str
dapat dijelaskan sebagai berikut.const char* str
: Nyatakan str untuk menjadi pointer ke const const. Ini berarti bahwa data yang menunjuk pointer ini konstan. Pointer dapat dimodifikasi, tetapi setiap upaya untuk mengubah data akan menimbulkan kesalahan kompilasi.str++ ;
: VALID . Kami memodifikasi pointer, dan bukan data yang diarahkan.*str = 'a';
: INVALID . Kami mencoba untuk memodifikasi data yang ditunjuk.char* const str
: Nyatakan str untuk menjadi pointer const ke char. Ini berarti bahwa titik sekarang konstan, tetapi data yang ditunjukkan juga tidak. Pointer tidak dapat dimodifikasi tetapi kita dapat memodifikasi data menggunakan pointer.str++ ;
: INVALID . Kami mencoba untuk memodifikasi variabel pointer, yang merupakan konstanta.*str = 'a';
: VALID . Kami mencoba untuk memodifikasi data yang ditunjuk. Dalam kasus kami ini tidak akan menyebabkan kesalahan kompilasi, tetapi akan menyebabkan kesalahan runtime , karena string kemungkinan besar akan masuk ke bagian read only dari biner yang dikompilasi. Pernyataan ini akan masuk akal jika kita telah mengalokasikan memori secara dinamis, misalnya.char* const str = new char[5];
.const char* const str
: Deklarasikan str untuk menjadi pointer const ke char const. Dalam hal ini kita tidak dapat memodifikasi pointer, atau data yang diarahkan.str++ ;
: INVALID . Kami mencoba untuk memodifikasi variabel pointer, yang merupakan konstanta.*str = 'a';
: INVALID . Kami mencoba untuk memodifikasi data yang ditunjukkan oleh pointer ini, yang juga konstan.Dalam kasus saya masalahnya adalah bahwa saya mengharapkan
constexpr char* str
untuk berperilakuconst char* str
, dan tidakchar* const str
, karena secara visual tampaknya lebih dekat dengan yang pertama.Juga, peringatan yang dihasilkan
constexpr char* str = "some string"
sedikit berbeda darichar* str = "some string"
.constexpr char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *const'
char* str = "some string"
:ISO C++11 does not allow conversion from string literal to 'char *'
.Tip
Anda dapat menggunakan Konversi Bahasa Inggris ↔ Bahasa Inggris untuk mengonversi
C
deklarasi ke pernyataan bahasa Inggris yang mudah dimengerti, dan sebaliknya. Ini adalah satu-C
satunya alat, dan karenanya tidak akan mendukung hal-hal (seperti constexpr) yang eksklusif untukC++
.sumber
Saya juga mendapat masalah yang sama. Dan apa yang saya lakukan sederhana hanya menambahkan const char * bukan char *. Dan masalah terpecahkan. Seperti yang orang lain sebutkan di atas, ini adalah kesalahan yang kompatibel. C memperlakukan string sebagai array ar sementara C ++ memperlakukan mereka sebagai array char ar.
sumber
Untuk apa nilainya, saya menemukan kelas wrapper sederhana ini berguna untuk mengubah string C ++ menjadi
char *
:sumber
Berikut ini mengilustrasikan solusinya, tetapkan string Anda ke pointer variabel ke array konstan char (string adalah pointer konstan ke array konstan char - plus panjang info):
sumber