代码 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;
}
有没有这两段代码会做不同事情的情况? 谢谢!
最佳答案
Is there ever any situation where these two blocks of code will do different things?
是的,当您在 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;
那么,这两个 body 是一样的吗?
foo* me = (foo*)this;
me->i = 1;
// and
this->i = 1;
答案是视情况而定,如前所述,它取决于函数的 const
特性。在非 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
。不过我不会冒险。
关于c++ - 以下 C++ 代码是否等价? (在智能指针实现中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2106899/