سؤال
وأنا لا يمكن العثور على الكثير من المعلومات عن const_cast
. المعلومات الوحيدة التي يمكنني أن تجد (على تجاوز المكدس) هي:
ويستخدم const_cast<>()
إضافة / إزالة CONST (نيس) (أو المتقلبة التي غمرت) متغير.
وهذا يجعلني عصبيا. يمكن استخدام السلوك سبب const_cast
غير متوقع؟ إذا كان الأمر كذلك، ما هي؟
وبدلا من ذلك، عندما هل هو بخير لاستخدام const_cast
؟
المحلول
وconst_cast
آمنة فقط إذا كنت يلقي المتغير الذي كان في الأصل غير const
. على سبيل المثال، إذا كان لديك دالة التي تأخذ معلمة من const char *
، وأنت تمر في char *
للتعديل، انها آمنة لconst_cast
تلك المعلمة مرة أخرى إلى char *
وتعديله. ومع ذلك، إذا كان المتغير الأصلي في الواقع const
، ثم استخدام const_cast
سوف يؤدي إلى سلوك غير معرف.
void func(const char *param, size_t sz, bool modify)
{
if(modify)
strncpy(const_cast<char *>(param), sz, "new string");
printf("param: %s\n", param);
}
...
char buffer[16];
const char *unmodifiable = "string constant";
func(buffer, sizeof(buffer), true); // OK
func(unmodifiable, strlen(unmodifiable), false); // OK
func(unmodifiable, strlen(unmodifiable), true); // UNDEFINED BEHAVIOR
نصائح أخرى
وأستطيع أن أفكر في حالتين حيث const_cast هي آمنة ومفيدة (قد تكون هناك حالات صالحة أخرى).
واحد هو عندما يكون لديك CONST المثال، إشارة، أو المؤشر، وتريد تمرير مؤشر أو إشارة إلى API غير-CONST الصحيح، ولكن ان كنت على يقين لن يقوموا بتعديل الكائن. يمكنك const_cast المؤشر وتمريرها إلى API، واثقين أنه لن يغير أي شيء في الواقع. على سبيل المثال:
void log(char* text); // Won't change text -- just const-incorrect
void my_func(const std::string& message)
{
log(const_cast<char*>(&message.c_str()));
}
ووالآخر هو إذا كنت تستخدم مترجم القديمة التي لا تنفذ "قابلة للتغيير، وكنت ترغب في إنشاء فئة غير CONST منطقيا ولكن ليس CONST أحادي المعامل. يمكنك const_cast 'هذا' داخل أسلوب CONST وتعديل أعضاء صفك.
class MyClass
{
char cached_data[10000]; // should be mutable
bool cache_dirty; // should also be mutable
public:
char getData(int index) const
{
if (cache_dirty)
{
MyClass* thisptr = const_cast<MyClass*>(this);
update_cache(thisptr->cached_data);
}
return cached_data[index];
}
};
وأجد أنه من الصعب أن نصدق أن هذا هو فقط م> معلومات يمكن أن تجد حول const_cast. نقلا عن في جوجل الثانية ضرب :
<اقتباس فقرة>إذا يلقي بعيدا constness ل الكائن الذي كان صراحة أعلن وCONST، ومحاولة ل تعديله، فإن النتائج تكون غير محددة.
ولكن، إذا كنت يلقي بعيدا constness من كائن له لا تم الإعلان صراحة CONST، ل يمكن تعديله بأمان.
اقتباس فقرة>وماذا يقول آدم. مثال آخر حيث const_cast يمكن أن تكون مفيدة:
struct sample {
T& getT() {
return const_cast<T&>(static_cast<const sample*>(this)->getT());
}
const T& getT() const {
/* possibly much code here */
return t;
}
T t;
};
ونحن أولا إضافة CONST إلى نقطة نوع this
ل، ثم نطلق النسخة CONST من getT
، وبعد ذلك إزالة CONST من نوع الإرجاع، التي هي سارية المفعول منذ t
يجب أن يكون غير CONST (على خلاف ذلك، وعدم CONST- لم يكن من الممكن دعا نسخة من getT
). هذا يمكن أن يكون مفيدا جدا إذا كنت حصلت على وظيفة الجسم كبير وكنت ترغب في تجنب كود زائدة عن الحاجة.
والجواب باختصار هو لا، انها ليست آمنة.
والجواب طويلة هو أنه إذا كنت تعرف ما يكفي لاستخدامه، ومن ثم ينبغي أن تكون آمنة.
وعندما كنت الصب، ما تقوله في الأساس هو، "أعرف شيئا المترجم لا يعرف". في حالة const_cast، ما تقوله هو، "على الرغم من أن هذا الأسلوب يأخذ في اشارة غير CONST أو المؤشر، وأنا أعلم أنه لن يغير المعلمة أمرر عليه".
وحتى إذا كنت لا تعرف فعلا ما كنت تدعي أن نعرف في استخدام المدلى بها، ثم لا بأس في استخدامه.
وأنت تدمير أي فرصة في موضوع السلامة، إذا قمت بتشغيل تعديل الأشياء التي المترجم يعتقد ان CONST.
#include <iostream>
using namespace std;
void f(int* p) {
cout << *p << endl;
}
int main(void) {
const int a = 10;
const int* b = &a;
// Function f() expects int*, not const int*
// f(b);
int* c = const_cast<int*>(b);
f(c);
// Lvalue is const
// *b = 20;
// Undefined behavior
// *c = 30;
int a1 = 40;
const int* b1 = &a1;
int* c1 = const_cast<int*>(b1);
// Integer a1, the object referred to by c1, has
// not been declared const
*c1 = 50;
return 0;
}
المصدر: <لأ href = "http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp؟topic=٪2Fcom.ibm.xlcpp8a.doc٪2Flanguage٪2Fref٪2Fkeyword_const_cast.htm "يختلط =" نوفولو "> http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp؟topic=٪2Fcom.ibm.xlcpp8a.doc٪2Flanguage٪2Fref٪2Fkeyword_const_cast.htm أ >