1

Visual Studio 2010 中是否有办法自动捕获在 NULL 对象上调用成员函数的错误?也许有一些标志,在每个成员函数的请求中都提出了适当的断言?

默认行为是静默接受它,并且仅在访问字段时崩溃。然而,在某些情况下,如果比原来的错误晚得多。


编辑:知道在指针上调用成员函数会NULL调用未定义的行为。这是我想要根除的代码中的一个错误。我希望 Visual Studio 有一些可以帮助我的非标准工具。

4

5 回答 5

2

不,这将毫无用处。

NULL对指针调用成员函数会调用未定义的行为。顾名思义,您无法确定此时的行为。

具体来说:

void MyObject::foo() {
    if (this) { throw std::logic_exception("this is NULL"); }

    std::cout << "Hello, world!\n";
}

可以由任何符合要求的编译器合理地更改为:

void MyObject::foo() {
    std::cout << "Hello, world!\n";
}

毕竟,标准this首先保证永远不会为空!

但是,可以做的不是依赖“裸”指针:

template <typename T>
class Pointer {
public:
    Pointer(): _ptr(nullptr) {}
    Pointer(T* t): _ptr(t) {}

    T* operator->() const { assert(_ptr); return _ptr; }
    T& operator*() const { assert(_ptr); return *_ptr; }

private:
    T* _ptr;
};

然后像使用指针一样使用它:

int main() {
    Pointer<MyObject> value = container.find("Element");
    value->foo();
}

如果它为空,则断言在foo尝试调用之前触发。

于 2013-03-10T14:38:01.377 回答
2

不,但如果你完全接受 RAII 并且只使用 C++11 智能指针(从不显式调用删除),你将很难遇到这样的错误。

于 2013-03-10T14:03:28.327 回答
1

您可以检查是否this为 NULL,但如果您在 MSVS 中运行,则应考虑使用DebugBreak- 选项,以强制调试中断以调查堆栈。这可能导致最有效的错误。我从 Release compiles 中删除了检查,因为在没有调试器的情况下运行该代码会使您的应用程序自行挂起,因为没有调试器可以告诉它继续。为了避免这个问题,你可以考虑 isDebuggerPresent()。

#ifdef DEBUG
#define CHECK() if (this==NULL) DebugBreak();
#else
#define CHECK() 
#endif

IsDebuggerPresent:

MSDN 上的 DebugBreak:

于 2013-03-10T14:40:23.670 回答
0

自动 - 我不知道,但你总是可以使用断言:

assert(this);

至于this并考虑它是一个引用“被调用者”类实例的关键字 - 它怎么可能是 NULL?通过 NULL 指针调用?

于 2013-03-10T14:02:36.160 回答
0

我不知道有什么特殊的选项可以检查这个,但你可以很容易地写一个宏:

 #define CHECK_THIS()  assert(this)

或者

 #define CHECK_THIS() do { if (this == NULL) { std::cerr << "'this' is NULL at " \
                             << __FILE__ << ":" << __LINE__ << " in " << __func__; \
                             exit(2); } while(0)

(它使用“do - while”以便可以将其放置在任何地方而不会干扰其他 if 语句等)。

然后只需添加CHECK_THIS()任何相关功能。

于 2013-03-10T14:01:51.480 回答