C++ 为什么是';这';不易挥发?

C++ 为什么是';这';不易挥发?,c++,symbian,C++,Symbian,在过去的几天里,我一直在调试一个多线程,其中一个线程正在删除另一个线程仍在使用的对象。我意识到,如果我能让“this”变得易变,那么诊断这个问题就会容易得多,也会快得多。它会将系统(Symbian OS)上的崩溃转储更改为信息量大得多的内容 那么,有什么理由不能或不应该这样做呢 编辑: 因此,确实没有安全的方法来防止或检查这种情况。如果说访问陈旧类指针的一种解决方案是使用一个保存指针的全局变量,并且调用的任何函数都应该是使用全局变量替换“this”的静态函数,那么这样说是否正确 static T

在过去的几天里,我一直在调试一个多线程,其中一个线程正在删除另一个线程仍在使用的对象。我意识到,如果我能让“this”变得易变,那么诊断这个问题就会容易得多,也会快得多。它会将系统(Symbian OS)上的崩溃转储更改为信息量大得多的内容

那么,有什么理由不能或不应该这样做呢

编辑: 因此,确实没有安全的方法来防止或检查这种情况。如果说访问陈旧类指针的一种解决方案是使用一个保存指针的全局变量,并且调用的任何函数都应该是使用全局变量替换“this”的静态函数,那么这样说是否正确

static TAny* gGlobalPointer = NULL;

#define Harness static_cast<CSomeClass*>(gGlobalPointer);

class CSomeClass : public CBase
    {
public:
    static void DoSomething();

private:
    int iMember;
    };


void CSomeClass::DoSomething()
    {
    if (!Harness)
        {
        return;
        }

    Harness->iMember = 0;
    }
static TAny*gGlobalPointer=NULL;
#定义线束静态接头(gGlobalPointer);
CSOMECASE类:公共CBase
{
公众:
静态空隙剂量仪();
私人:
内部成员;
};
void CSomeClass::DoSomething()
{
如果(!线束)
{
返回;
}
线束->iMember=0;
}
因此,如果另一个线程删除并使全局指针为空,它将立即被捕获


我认为这其中的一个问题是,如果编译器缓存了harnese的值,而不是每次使用它时都检查它。

可能是这样的。只需将成员函数声明为volatile

struct a
{
    void foo() volatile {}
};

这不是一个变量,而是一个常量。您可以更改此引用的对象,但不能更改其值。因为常数永远不会改变,所以没有必要将它们标记为volatile。

volatile对您没有帮助。
struct a
{
    void foo() volatile {}
};
它将使对变量的访问变得易变,但不会等待任何方法完成

使用智能指针


还有一个版本,在新的C++版本中,STD。

它没有帮助:使变量易失性意味着编译器将确保每次访问时它都从内存中读取值,但是<>代码> < <代码>的值不会改变,即使从不同的上下文或相同的情况来看,您可以删除它所指向的对象。

如果在删除对象时正在读取该对象,则这是一个清除内存错误,与volatile无关

struct a
{
    void foo() volatile {}
};
volatile用于阻止编译器“记住”内存中可能由不同线程更改的变量的值,即阻止编译器优化

e、 g.如果您的类有一个指针成员p,并且您的方法正在访问:

p->a;
p->b;
p在“this”中是不稳定的,因此
p->b
访问的对象可能与它访问
p->a
时不同

如果p被破坏了,尽管“this”被删除了,那么volatile将不会拯救您。大概你认为它会被“空”,但它不会


顺便说一句,如果析构函数锁定互斥锁以保护使用同一对象的另一个线程,这也是一条非常合理的规则,那么您就有问题了。您的析构函数可能会锁定,因为它从需要同步活动的外部对象中删除自己的存在,但不是为了保护自己的成员。

您的意思是,如果
是易失性的,它会更容易锁定,还是说如果
是指向易失性的指针,它会更容易锁定?换句话说,您是否在崩溃转储中看到
this
(这似乎有点奇怪,因为它从未更改)或某个数据成员的过期值?为了回答实际问题,默认情况下不会发生这种情况的原因是,您无法将
this
传递给指针指向non-volatile的函数。同样的原因
除非您标记成员函数
const
,否则该
不是指向const的指针。。。。因为删除指针(特别是它指向的内存)不会神奇地将指针设置为
0
。编译器无法知道对象的指针在哪里。而“常数”是指“代码> t*const < /Cord>,而不是<代码> const t*< /Cord>。C++中的答案并不完全有意义。代码>这是一个表达式。在C++中,
const
表达式肯定会改变:
intx=0;int const*px=&x;std::cout@Mike不,他不是指
t*const
他指的是一个不是对象的
t*
。将
设置为const
也没有意义。好吧,至少我认为他是这个意思。否则他的回答对我来说毫无意义@Mike yes
这更像是一个“指针文字”。反正是右值。它是
+a
而不是
a
。“它看起来像一个,工作起来像一个”不是真的。试试
&这个
。或者尝试
模板void f(T&)调用
f(this)
。如果
this
T*const
变量,这两个变量都可以工作。@Mike:9.3.2§1说:“在非静态(9.3)的主体中成员函数,关键字
this
是一个prvalue表达式,其值为调用函数的对象的地址。类
X
的成员函数中
this
的类型为
X*
。如果声明成员函数
const
,则
this
的类型为
const X* */COD>之后,没有<代码> const 。Symbian C++中没有智能指针。我不希望它提供同步,我希望它在访问过时的指针时崩溃。@詹姆斯:不幸的是,使其易失性无法实现这一点。共享指针是模板类。。您可以卸载它并添加到项目中