無法用 "ATTRIB_GEN_STRING *" 類型的值初始化 "ATTRIB_GEN_NAME *&" 類型的引用(非常量限定)

        在ACIS中,很多下行強制(downcast)轉換是安全的,如對一個ENTITY*指針強制使用(BODY*)從來沒有出現過問題。

        今天碰到的是api_find_named_attribute這個函數,原型如下。

    DECL_GA outcome api_find_named_attribute(
    ENTITY*           ent,
    const char*       name,
    ATTRIB_GEN_NAME *&ret_att,
    AcisOptions *ao = NULL);

        我一般用這個的時候,是這樣的操作:

    ATTRIB_GEN_NAME *na;//用ATTRIB_GEN_STRING* na 會出錯
    api_find_named_attribute(pFace,"名稱",na);
    char* cpName = ((ATTRIB_GEN_STRING*)na)->value();//下行強制轉換

        其中,ATTRIB_GEN_STRING類的部分定義如下,公有繼承於ATTRIB_GEN_NAME,多了個Value的成員數據和value()的成員函數。

class DECL_GA ATTRIB_GEN_STRING: public ATTRIB_GEN_NAME {

	char *Value;

public:
	/**
	 * Returns the string value contained by this attribute.
	 */
	char const *value() const {return Value;}

        上面的操作過後,這樣會得到那個pFace的“名稱”屬性的值cpName。這裏不用dynamic_cast也不會出問題,說明na在函數裏面實際指向的是一個ATTRIB_GEN_STRING對象。

        然後想,如果na是ATTRIB_GEN_STRING*類型,是不是就省去了後面的強制轉換或者dynamic_cast操作了?答案是否定的,VS給出了錯誤:無法用 "ATTRIB_GEN_STRING *" 類型的值初始化 "ATTRIB_GEN_NAME *&" 類型的引用(非常量限定)。指針可以上行轉換(upcast),但是指針引用是不可以上行轉換的。

        這裏其實是引用的性質問題了,跟上行不上行沒關係了。一方面,引用類似於一個*const的指針,另一方面,引用必須與被引用的對象類型一致(常引用有例外)。考慮這段代碼:

	double dou = 2.33;
	int &in1 = dou;//報錯,無法用 "double" 類型的值初始化 "int&" 類型的引用(非常量限定)
	const int &in2 = dou;//不報錯
        是不是跟上面的很相像?括號裏的“非常量限定”非常微妙啊。這說明,如果int類型的in1引用了double類型的dou,那麼int的整數操作就要用在double類型上了,這是不安全的。編譯器可能做了類似下面的操作:
    double dou= 2.33;
    int temp = dou;
    int& in1 = temp;

        那麼對in1的操作根本應用不到dou上了,但是const引用就不一樣了:反正不能被修改。

        所以這個問題應該是ACIS內部做了優化,所以下行轉換不會出問題,看不到它的源碼,只能這樣猜想了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章