2012-03-01 72 views
0

新命令在堆中分配內存來存儲對象。 靜態分配可能會導致將對象放在堆棧上。 但它們都不是內存保護區。 我可以訪問這個,它是對象的只是地址,然後使用間接運算符,所以指向的對象字段:明顯封裝

string str=string("hello"); 
void** str_this=(void**)&str; 
char* str_data= (char*)*str_this; 
str_data[0]='s'; 
str_data[1]=0; 
cout <<str_data; // prints "sello" 

所以這仍然被認爲是封裝?是否負責類實例化用戶(誰實例化對象)以避免數據泄露?

+0

C++標準和它的這部分基於的OOP原則是共享約定,而不是法規。根據自己的需要,您可以隨意遵守或不遵守您的意見。就我個人而言,我覺得服從封裝總是有用的。你可能會發現違反封裝有用。給他自己的。 – 2012-03-01 19:14:59

回答

6

編程中的封裝通常並不意味着「如果你確實真的嘗試不可能解決問題」。

它通常意味着更接近「能夠明確區分什麼是假設要被暴露或沒有被暴露或不被意外暴露或使用」。

我不認爲任何人都會誤認爲你的代碼是以它應該訪問的方式訪問字符串的。

2

你的代碼隱式地依賴於std :: string的特定實現。換句話說,你的代碼是,打破了封裝的std :: string。更糟糕的是,它調用未定義的行爲,所以它可能工作,或者它可能不會,或者它可能會崩潰...

3

C++是一種功能強大的語言。正如一位漫畫書超級英雄曾經說過的那樣,擁有巨大力量的人有很大的責任感。

一旦你施放一個對象指針void*,然後重鑄該指針爲另一種類型,在這種情況下char*,你已經進入的未定義行爲土地。如果您嘗試使用char*指針,該語言不會保證什麼會和什麼不起作用。將void*重新改回原始類型(string*)只是合法的。

調用未定義的行爲沒有違反封裝的合法的方式,因爲一旦你越過那條未定義行爲門檻,什麼是可能的(只是不便攜式)。