有没有办法让成员函数不能从构造函数中调用?

Is there a way to make member function NOT callable from constructor?

我有使用

的成员函数(方法)
std::enable_shared_from_this::weak_from_this() 

简而言之:weak_from_this returns weak_ptrthis。一个警告是它不能从构造函数中使用。 如果有人在继承 class、weak_from_this 的构造函数中使用我的函数,它会 return 过期 weak_ptr。我通过断言检查它是否未过期来防止这种情况,但这是 运行 次检查。

有没有办法在编译时检查它?

恐怕答案是 "no, it's not possible to protect against this at compile-time." 总是很难证明是否定的,但考虑一下:如果有可能以这种方式保护功能,它可能已经完成了 weak_from_thisshared_from_this 在标准库中。

不,没有办法。考虑:

void call_me(struct widget*);

struct widget : std::enable_shared_from_this<widget> {
    widget() {
        call_me(this);
    }

    void display() {
        shared_from_this();
    }
};

// later:

void call_me(widget* w) {
    w->display(); // crash
}

问题是您要检查是否没有在构造函数中调用 shared_from_this 是有原因的。想想这个原因。不是 shared_from_this 不能调用,是因为它的 return 值还没有办法赋值。这也不是因为它永远不会被分配。因为在代码的执行中稍后会被赋值。运行顺序是你程序的运行时间属性。您不能在编译时断言操作顺序,这是在运行时完成的。

不是这样,但是 - 如果性能不是问题,您可以添加一个标志来指示构造已完成,并使用它在 运行 时通过此类调用失败:

class A {

    // ... whatever ...
public:
    A() { 
        // do construction work
        constructed = true;
    }

    foo() {
        if (not constructed)  { 
            throw std::logic_error("Cannot call foo() during construction"); 
        }
        // the rest of foo
    }

protected:
    bool constructed { false };
}

您还可以让这些检查仅在 DEBUG 模式下编译时适用(例如,使用预处理器进行条件编译 - #ifndef NDEBUG),这样在 运行 时您就不会受到性能损失.不过请注意 noexcepts。

投掷的替代方法是 assert()'ing。