以下C ++代码是否相同? (在智能指针实现中)

时间:2010-01-21 04:21:01

标签: c++ templates pointers

代码1:

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;
}

是否有任何情况,这两个代码块会做不同的事情? 谢谢!

2 个答案:

答案 0 :(得分:7)

  

是否有任何情况下这两个代码块会做不同的事情?

是的,当您使用const方法时。目前,具有me的那个调用未定义的行为。原因如下:

如您所知,当您调用成员函数时,会有一个隐式this指针。当函数标记为this时,const指针为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。我不会抓住机会。

答案 1 :(得分:2)

或多或少GMan所说的一切,除了引用_不必是可变的。它也可以是一个覆盖operator ++()的对象,它是一个const成员函数。