2010-01-21 47 views
2

代碼1:以下是C++代碼嗎? (在智能指針實現)

template<class T> 
const PtrInterface<T>* 
PtrInterface<T>::newRef() const { 
    PtrInterface<T>* me = (PtrInterface<T>*) this; 
    ++me->references_; 
    //++this->references_; 
    return this; 
} 

代碼2:

template<class T> 
const PtrInterface<T>* 
PtrInterface<T>::newRef() const { 
    //PtrInterface<T>* me = (PtrInterface<T>*) this; 
    //++me->references_; 
    ++this->references_; 
    return this; 
} 

是否有過任何情況下的代碼這兩個塊將做不同的事情? 謝謝!

+1

'references_'是否可變?這是一個重要的細節。 – GManNickG

回答

7

是否有任何情況下這兩個代碼塊會做不同的事情?

是的,當你在const方法。目前,與me調用未定義的行爲。原因如下:

如您所知,當您調用成員函數時,會有一個隱含的指針this。當函數被標記爲const時,this指針爲const。藉此,例如:

struct foo 
{ 
    void method1(void); 
    void method2(void) const; 

    int i; 
}; 

含蓄,編譯器生成(順便說一句,這是簡化的):

void foo::method1(foo* this); 
void foo::method2(const foo* this) const; 

那麼,這兩個機構一樣嗎?

foo* me = (foo*)this; 
me->i = 1; 

// and 

this->i = 1; 

答案是這取決於,並且如前所述,它是依賴於const -ness的功能。在非const功能,它們是相同的:

void foo::method1(foo* this) 
{ 
    foo* me = (foo*)this; // this cast is redundant 
    me->i = 1; 

    // ... 

    this->i = 1; 
} 

但在const功能:

void foo::method2(const foo* this) const 
{ 
    foo* me = (foo*)this; // uh-oh! acts like const_cast 
    me->i = 1; // modifying a const_cast'd variable is undefined behavior 

    // ... 

    this->i = 1; // wouldn't compile 
} 

我們最終剝離const路程。所以,不,它們並不總是一樣的。這是C風格演員的危險:它會找到一種方法。順便說一句,鑄造const本身不是未定義的行爲;這是所述變量的修改。

雖然在你的問題中有一個棘手的問題:你的代碼不應該編譯。像上面註釋過的代碼一樣,在您的const方法中,您應該無法修改reference_

這是不同的,如果reference_mutable,我猜它可能是(假設你給我們編譯代碼。)在這種情況下,我不能肯定,如果第一個樣品導致不確定的行爲,因爲它是首先是mutable。我不會冒這個機會。

+0

很好的編輯,但最後的回答是短暫而甜蜜的:)它差異去通過長的答案,而不失去重點:) –

+0

@Yogesh:我覺得舊的難以遵循,這是一步一步「不要做到這一點「。 :P – GManNickG

2

GMan說的幾乎所有的東西,除了參考文獻_不必是可變的。它也可以是一個重載operator ++()成爲const成員函數的對象。

+1

的確如此,儘管這比我想像的還要醜陋。 – GManNickG