它是合法的C ++测试的一个成员函数这个指针?(Is it legal C++ to test th

2019-07-18 00:16发布

我有涉及不同类类型对象的应用程序。 目的是通过指针引用。 一个空指针表示该关联的对象不存在。 目前,调用代码很麻烦,因为每次它使用一个指向对象的指针,它测试空指针值,并采取了一些相应的动作为null。 由于采取在不存在的情况下,默认的操作取决于对象的类型,我宁愿它编码的类对象本身,而不是在调用程序。 这导致类似下面的结构:

class C
{ ... 
  void member_func() //non-virtual !
  { if (this) { do something with the object ... }
    else { take some default action }
  }
  ...
};

显然,成员函数不能是虚拟的,因为当对象不存在查找表不存在,和虚拟呼叫将会失败。 但是,这是合法的代码C ++非虚成员函数? 这似乎对我已经尝试过的编译器正常工作,但我担心可能的非便携性。 在标准我无法找到一个条款,要么明确允许或明确禁止这样的结构。

Answer 1:

this永远不会为空的成员函数,所以你执行检查是无用的。

正如评论指出由马修M.,如果你做这样的事情在你的代码:

C* c = 0; 
c->member();

这会导致不确定的行为 ,这是一件坏事



Answer 2:

正如已经指出的那样, this绝不是一个空指针。 如果是,你已经调用未定义的行为。 你可以,而是创建一组重载函数,就像这样:

void DoTheThing(C* cp)
{
    if (cp)
        cp->member_func();
    else
    {
        // take some default action
    }
}

void DoTheThing(B* bp)
{
    if (bp)
        bp->some_other_member_func();
    else
    {
        // take some default action
    }
}

如果你要调用的函数在每个类相同的名字,那么你可以让每个执行该类(都具有相同的名称)的默认操作类的静态功能,使模板:

template<typname T>
void DoTheThing(T* tp)
{
    if (tp)
        tp->member_func();
    else
        T::default_action()
}


Answer 3:

标准明智的,代码是不合法的, 它在实践中(不好的做法就是)使用。

事实上,IIRC MFC内部使用这些检查。



Answer 4:

检查是否this == NULL是没有问题的。 通过一个零目标指示字调用一个方法是。

如果你想保持检查的地方,你可以把它放在一个智能指针类,如果持有指针为NULL,可以采取适当的行动。 如果“适当的行动”唯一地由持有类型决定的,你可以使用一个traits类来指定。

这样你的NULL检查和它们的逻辑被保持在一起,并且不混入任何主叫或方法的代码。


// specialize this to provide behaviour per held type
template <typename T> struct MaybeNullDefaultAction {
    void null_call() { throw std::runtime_error("call through NULL pointer"); }
}

template <typename T> class MaybeNull: MaybeNullDefaultAction<T> {
    T *ptr;
public:
    explicit MaybeNull(T *p) : ptr(p) {}

    T* operator-> () {
        if (!ptr)
            null_call();
        // null_call should throw to avoid returning NULL here
        return ptr;
    }
};

不幸的是,我看不到的方式来做到这一点没有丢。 有没有办法拦截所有的方法名称的函数调用,否则我刚刚返回*thisoperator->和做的工作在operator()



Answer 5:

我认为,这是不允许这样做。 你问到标准的引用。 我相信,感兴趣的第一件事是9.3.1非静态成员函数,1:

非静态成员函数可以被称为为它的类类型的对象,或者用于从它的类类型的类衍生的(第10章)的目的,使用类的成员访问语法(5.2.5,13.3.1.1)。

其次让我们来看看5.2.5类成员访问,2:

。E1-> E2被转换为等效的形式(*(E1))E2的表达; 在5.2.5剩余部分将只解决了第一个选项(点)。

所以,如果E1是nullptr,将* E1将不会被允许。 所以,至少是我的猜测。



文章来源: Is it legal C++ to test the this-pointer in a member function?
标签: c++ null this