我在实验室中看到了这段代码片段,它实际上是在MSVC2008和G ++中编译的。
void LinkList< class T >::Insert(T n)
{
if (this == NULL)
// some code here
}
据我所知,this
不能为null,因为如果没有实例化,你就不能在c ++中调用类函数。这是一个有效的代码吗?如果是这样,背后的原因是什么?它有用吗?
答案 0 :(得分:8)
因为如果没有实例化,你就不能在c ++中调用类函数
问题是,你可以,但leads to undefined behavior。
这样的检查可能应该是一个断言,尽管这样的代码不能保证按标准实际工作。 (如果this
为空,那么您已经处于未定义的行为状态。)
它“有用”的原因是在删除对象后使用对象进行检测,或者从未创建对象:
template <typename T> // I hate this function
void safe_delete(T*& pPtr)
{
delete pPtr;
pPtr = 0;
}
T* p = new T;
safe_delete(p);
p->foo(); // this is null, and we've entered undefined behavior
在foo
内你可以断言,“嘿,我们搞砸了:/”。
在我看来,这种用途表明设计不好。你不应该有一个可能再次被调用的指针。你用指针做的最后一件事是delete
它;如果它在此之后仍然存在,请更改您的代码,使其不是。
答案 1 :(得分:5)
这是它试图'解决'的问题类型:
class A
{
public:
void test()
{
if(this == NULL)
{
std::cout<<"This is NULL\n";
}
}
};
int main() {
A* p = NULL;
p->test();
return 0;
}
但是,请注意,调用p->test()
会调用未定义的行为,因此this
可能为NULL,也可能不为NULL。我的猜测是有人真的很匆忙而选择这样做而不是解决实际问题。不要使用它,它永远不会可靠或可预测地工作。关于它为什么编译,this
只是一个const指针,比较指向NULL
的指针在语法上是有效的。
答案 2 :(得分:0)
如果没有实例化类变量...它的行为是未定义的...所以编译器不会给你错误...但是函数的行为是未定义的...如果在{{1之前“它可以运行得非常好语句没有使用任何类成员......
答案 3 :(得分:0)
因为this
只是一个指针,所以代码有效 - 这意味着比较是有效的。是否执行条件块中的代码是另一个问题。
答案 4 :(得分:0)
根据C ++标准,它是未定义的行为。但是,典型的C ++实现将处理非虚拟成员函数
void A::func(int arg);
喜欢C风格的功能
void A_func(A* this, int arg);
就像任何指针参数一样,只要你不取消引用内存,“this”就可以为NULL。所以,如果你写:
#include <iostream>
class A
{
public:
void test();
};
void A::test()
{
std::cout << "This function could have been static." << std::endl;
}
int main()
{
((A*) NULL)->test();
return 0;
}
它运行得很好(至少在MSVC和G ++下)。
但是,这会产生分段错误:
#include <iostream>
class A
{
public:
void test();
private:
int _n;
};
void A::test()
{
_n = 42;
}
int main()
{
((A*) NULL)->test();
return 0;
}
if(this == NULL)检查是为了防止空指针取消引用导致程序崩溃。
但为了符合标准,最好从外面进行测试。
if (pList != NULL)
{
pList->Insert(value);
}