[英]c++ const member function
我正在閱讀一本名為“Effective C ++,Second Edition”的書,以及它關於const成員函數以及你如何具有逐位常量和概念常數的討論。
它說大多數編譯器都會使用按位常量,這是因為你無法改變const成員函數內對象的數據成員。
然后是一個成員函數的例子,它似乎在const測試中沒有按位。
它是這樣的:
#include "stdafx.h"
#include <string>
#include <iostream.h>
using namespace std;
class mystring
{
public:
mystring(const char* value);
operator char *() const { return data; }
private:
char * data;
};
mystring::mystring(const char * value)
{
mystring::data = const_cast<char*>(value);
}
int main(int argc, char* argv[])
{
const mystring s = "Hello";
char * nasty = s;
*nasty = 'M';
printf("s: %c", s);
return 0;
}
當它運行時,它在我的書中說它應該允許你改變s
的值,即使它是const
。 這是因為char *數據指向與const char*
value指向的相同。 *data
這種情況下的*data
不是const
。
但是,嘗試在MS VC ++ 6.0中運行它,它會在行*nasty = 'M';
處拋出訪問沖突*nasty = 'M';
有人可以解釋發生了什么嗎? 我想我錯過了什么?
對我而言,似乎因為我們有一個const mystring s
,我們不應該改變它,但是它在書中所說的內容似乎很尷尬。
訪問沖突是因為您嘗試更改字符串文字。 您的代碼相當於:
char * p = "Hello";
* p = 'M';
這在C和C ++中都是非法的 - 與const成員函數無關。
您只能獲得訪問沖突,因為char*
指針是字符串文字。 更改字符串文字是未定義的行為(在您的情況下為AV),它與const-correctness無關。
你正在做的是未定義的行為。 您正在拋棄常量並嘗試修改常量值。 如果該示例已按原樣從書中復制,則該書是錯誤的。
與const_cast<>
合法的是將const_cast<>
從常量指針/引用轉移到非const對象:
int i = 5;
int const & ir = i;
const_cast<int&>(ir) = 7; // valid
int const * ip = &i;
*const_cast<int*>(ip) = 9; // valid
const int c = 11;
int const & cr = c;
const_cast<int&>(cr) = 13; // Undefined behavior
你不能從對真正的const對象的引用中拋棄const的原因是編譯器可以決定將對象放在只讀內存中,在這種情況下操作可能以不同的方式失敗(殺死應用程序,忽略改變...)
在你的榜樣,你不換s
,嘗試記憶改變,其中的成員變量s
點。 由於允許將const
放在很多地方,因此必須注意實際聲明const
。
您的成員函數operator char*() const
不允許更改任何成員變量。 嘗試operator char *() const { data = "something else"; return data; }
operator char *() const { data = "something else"; return data; }
operator char *() const { data = "something else"; return data; }
和你的編譯器會告訴你,你是不允許修改data
。 但是,在這種情況下,您只需返回data
而無需修改。 這是允許的。 您甚至可以更改data
指向的內存,如operator char *() const { *data = 'M'; return data; }
operator char *() const { *data = 'M'; return data; }
operator char *() const { *data = 'M'; return data; }
。 但是,由於data
指向不允許更改的字符串文字,因此在您的上下文中會失敗。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.