Friday, September 17, 2010

C + + motto: as long as possible on the use of const


Unfortunately, a lot of member functions and constants can not be completely through the bits of the test. In particular, a constantly changing the contents of a pointer to member function. Unless the pointer in the object, or bits of this function is const, the compiler will not raise objections. For example, suppose we have a similar TextBlock class, because it needs to know with a string of the mass of the C API dealing with, so it needs to its data stored as char * instead of string.

class CTextBlock (
public:
...
char & operator [] (std:: size_t position) const / / inappropriate (but bitwise

(Return pText [position];) / / const) declaration of
/ / Operator []
private:
char * pText;
);
Although the operator [] returns the object reference to internal data, this class is (inappropriate) it is declared const member function (Item 28 will be talking about a subject in depth). First it aside and see if operator [] to achieve, it does not use any means to change the pText. Result, the compiler generates pleasure operator [] code, because all the compiler is concerned, it is bits const, but we see what happens: const CTextBlock cctb ("Hello"); / / declare constant object

char * pc = & cctb [0]; / / call the const operator [] to get a
/ / Pointer to cctb's data

* Pc = 'J'; / / cctb now has the value "Jello"
Here indeed is a problem, you use a fixed value to create a constant object, and then you just use it to call a const member function, but you change its value! This leads to the notion of logical constants. Adherents of this theory that: a const member function is called when the object may change some bits, but only with the customer can not feel the approach. For example, your CTextBlock class can be stored when required length of the text block: class CTextBlock (
public:
..
std:: size_t length () const;

private:
char * pText;
std:: size_t textLength; / / last calculated length of textblock
bool lengthIsValid; / / whether length is currently valid
);

std:: size_t CTextBlock:: length () const
(
if (! lengthIsValid) (
textLength = std:: strlen (pText); / / error! can't assign to textLength
lengthIsValid = true; / / and lengthIsValid in a const
) / / Member function
return textLength;
)
length of the realization of course, not bits const's - textLength and lengthIsValid are likely to be changed - but it is also seen as an object of the const CTextBlock effective. However, the compiler does not agree, it insisted constants of binary bits, how do?

Solution is simple: Use the keyword mutable as the expression of C + + the const-related flexible space. mutable non-static data members of the binary bits from the binding constants of the liberation: class CTextBlock (
public:
...
std:: size_t length () const;

private:
char * pText;
mutable std:: size_t textLength; / / these data members may
mutable bool lengthIsValid; / / always be modified, even in
); / / Const member functions

std:: size_t CTextBlock:: length () const
(
if (! lengthIsValid) (
textLength = std:: strlen (pText); / / now fine
lengthIsValid = true; / / also fine
)
return textLength;
)
To avoid the const and non-const member function of repetition

mutable constants of binary bits for the solution not the problem to my mind is a good solution, but it can not solve all of the const-related problems. For example, suppose TextBlock (including CTextBlock) of the operator [] only to return an appropriate character reference, it should conduct border inspections, record visit information, even to confirm data integrity, these functions to const and non-const The operator [] function, so that they become such a monster as follows: class TextBlock (
public:
..
const char & operator [] (std:: size_t position) const
(
... / / Do bounds checking
... / / Log access data
... / / Verify data integrity
return text [position];
)
char & operator [] (std:: size_t position)
(
... / / Do bounds checking
... / / Log access data
... / / Verify data integrity
return text [position];
)
private:
std:: string text;
);
Oops! You mean to repeat the code? There followed additional compile time, maintenance costs and headaches code expansion and other things? Of course, you can also shift the border check, and all code to a separate member function (of course, private) and to allow the two versions of operator [] to call it, but you still have to repeat the call to the function and write return statement of the code.

How can only achieve an operator [] function, but also can be used twice? You can use a version of operator [] to call the other version. Removed by force constants of transition.

As a general rule, force restructuring is a very bad idea, I will spend an entire Item to tell you not to use it, but the repetition code is not a good thing. Under the current circumstances, const version of operator [] is doing is precisely the non-const version did, the only difference is that it has a const return type. In this case, by removing the return type of the constant transformation of a security, because no matter who call non-const operator [], the first condition is a non-const object. Otherwise, he could not call a non-const function. So, even if requires a mandatory transition to non-const operator [] call the const version of the method in order to avoid duplication of code is safe. The code below, then the explanation may make you understand it more clearly: class TextBlock (
public:
...
const char & operator [] (std:: size_t position) const / / same as before
(
...
...
...
return text [position];
)
char & operator [] (std:: size_t position) / / now just calls const op []
(
return
const_cast (/ / cast away const on
/ / Op [] 's return type;
static_cast (* this) / / add const to * this's type;
[Position] / / call const version of op []
);
)
...
);
As you can see, there are two mandatory code transformation, not just one. We allow non-const operator [] calls const version, but if the non-const operator [] of the interior, we just call the operator [], then we will recursively call ourselves a million times or more. Wei Liao avoid infinite recursion, we must be clear that we want to call const operator [], not directly in the way to do this, so we will * this type have been from Ta TextBlock & Jiangzhizhuanxing Dao const TextBlock &. Yes, we use force in transition, it added a const! So we have two mandatory transition: the first is for * this with const (purpose is when we call the operator [] when the call is const version), the second is from the const operator [] return value being removed const.

Increase the mandatory transition const is a safe conversion (from a non-const object to a const object), so we do use static_cast. Remove const const_cast mandatory transition can be accomplished, where we have no other choice.

The basis of the completion of other things, we call in this case an operator, so the syntax may seem strange. Cause it will not win the beauty contest, but it passed in the const version of operator [] on to achieve its non-const version of the method to avoid duplication of code to achieve the desired results. The syntax to use ugly best achieve our goals whether it is worth to you to decide, but this in a const member function on the basis of its non-const version of the technology is very worthwhile to master.

銆??鏇村姞鍊煎緱鐭ラ亾鐨勬槸鍋氳繖浠朵簨鐨勫弽鍚戞柟娉曗?鈥旈?杩囩敤 const 鐗堟湰璋冪敤 non-const 鐗堟湰鏉ラ伩鍏嶄唬鐮侀噸澶嶁?鈥旀槸浣犱笉鑳藉仛鐨勩?璁颁綇锛屼竴涓?const 鎴愬憳鍑芥暟鎵胯涓嶄細鏀瑰彉瀹冪殑瀵硅薄鐨勯?杈戠姸鎬侊紝浣嗘槸涓?釜 non-const 鎴愬憳鍑芥暟涓嶄細鍋氳繖鏍风殑鎵胯銆傚鏋滀綘浠庝竴涓?const 鎴愬憳鍑芥暟璋冪敤涓?釜 non-const 鎴愬憳鍑芥暟锛屼綘灏嗛潰涓翠綘鎵胯涓嶄細鍙樺寲鐨勫璞¤鏀瑰彉鐨勯闄┿?杩欏氨鏄负浠?箞浣跨敤涓?釜 const 鎴愬憳鍑芥暟璋冪敤涓?釜 non-const 鎴愬憳鍑芥暟鏄敊璇殑锛屽璞″彲鑳戒細琚敼鍙樸?瀹為檯涓婏紝閭f牱鐨勪唬鐮佸鏋滄兂閫氳繃缂栬瘧锛屼綘蹇呴』鐢ㄤ竴涓?const_cast 鏉ュ幓鎺?*this 鐨?const锛岃繖鏍峰仛鏄竴涓樉鑰屾槗瑙佺殑楹荤儲銆傝?鍙嶅悜鐨勮皟鐢ㄢ?鈥斿氨鍍忔垜鍦ㄤ笂闈㈢殑渚嬪瓙涓敤鐨勨?鈥旀槸瀹夊叏鐨勶細涓?釜 non-const 鎴愬憳鍑芥暟瀵逛竴涓璞¤兘澶熶负鎵?涓猴紝鎵?互璋冪敤涓?釜 const 鎴愬憳鍑芥暟涔熸病鏈変换浣曢闄┿?杩欏氨鏄?static_cast 鍙互鍦ㄨ繖閲屽伐浣滅殑鍘熷洜锛氳繖閲屾病鏈?const-related 鍗遍櫓銆?br />
銆??灏卞儚鍦ㄦ湰鏂囧紑濮嬫垜鎵?鐨勶紝const 鏄竴浠剁編濡欑殑涓滆タ銆傚湪鎸囬拡鍜岃凯浠e櫒涓婏紝鍦ㄦ秹鍙婂璞$殑鎸囬拡锛岃凯浠e櫒鍜屽紩鐢ㄤ笂锛屽湪鍑芥暟鍙傛暟鍜岃繑鍥炲?涓婏紝鍦ㄥ眬閮ㄥ彉閲忎笂锛屽湪鎴愬憳鍑芥暟涓婏紝const 鏄竴涓己鏈夊姏鐨勭洘鍙嬨?鍙鍙兘灏辩敤瀹冿紝浣犱細涓轰綘鎵?仛鐨勬劅鍒伴珮鍏淬?

Things to Remember

銆??路灏嗘煇浜涗笢瑗垮0鏄庝负 const 鏈夊姪浜庣紪璇戝櫒鍙戠幇浣跨敤閿欒銆俢onst 鑳借鐢ㄤ簬瀵硅薄鐨勪换浣曡寖鍥达紝鐢ㄤ簬鍑芥暟鍙傛暟鍜岃繑鍥炵被鍨嬶紝鐢ㄤ簬鏁翠釜鎴愬憳鍑芥暟銆?br />
銆??路缂栬瘧鍣ㄥ潥鎸佷簩杩涘埗浣嶅父閲忔?锛屼絾鏄綘搴旇鐢ㄦ蹇典笂鐨勫父閲忔?锛坈onceptual constness锛夋潵缂栫▼銆傦紙姝ゅ鍘熸枃鏈夎锛宑onceptual constness 涓轰綔鑰呭湪鏈功绗簩鐗堜腑瀵?logical constness 鐨勭О鍛硷紝姝f枃涓殑绉板懠鏀逛簡锛屾澶勫嵈娌℃湁鏀广?鍏跺疄姝ゅ杩樻槸浣滆?鏂板姞鐨勯儴鍒嗭紝鍗翠娇鐢ㄤ簡鏃х殑鏈锛屾?锛佲?鈥旇瘧鑰咃級

銆??路褰?const 鍜?non-const 鎴愬憳鍑芥暟鍏锋湁鏈川涓婄浉鍚岀殑瀹炵幇鐨勬椂鍊欙紝浣跨敤 non-const 鐗堟湰璋冪敤 const 鐗堟湰鍙互閬垮厤閲嶅浠g爜銆?br />





相关链接:



Easy to use File Compression



A clear DEFINITION of the ITU IPTV IPTV in China will affect the direction



C + + Monitor: Compatible With The Accepted Type Of Member Function Templates



Directory Astrology Or Biorhythms Or Mystic



To the ants and the Express "COSMETIC"



Matting, Photoshop master of the Road, 2



Strategy And War Games Infomation



Gmail FREQUENTLY dropped a solution



Ts Format Converter



convert m4a to mp3 ONLINE



free mp3 to aac CONVERTER



Easy Cataloging



Small window, Big World Comparative evaluation Pocket PC 8



mts To mpg



Sybase raise money for love during the full Sichuan



Photoshop Production - wire and spark



BenQ CD-R/RW discs identify the true and false



No comments:

Post a Comment