2010-01-21 50 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