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

时间:2019-04-08 14:53:06

标签: c++ constructor c++17 shared-ptr weak-ptr

我有使用

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

简而言之:weak_from_this返回weak_ptr this 。一个警告是它不能从构造函数中使用。 如果有人使用继承的类的构造函数中的函数,则其中的weak_from_this将返回过期的weak_ptr。我通过断言检查它是否未到期来进行防范,但这是运行时检查。

有没有一种方法可以在编译时进行检查?

3 个答案:

答案 0 :(得分:15)

恐怕答案是“不,不可能在编译时对此加以保护”。总是很难证明它是否定的,但是请考虑一下:如果可以通过这种方式保护一个函数,那么标准库本身中的 myNewShape = myShapeFactory.getShape("T"); myNewShape.inheritProperties(myShape); Toast.makeText(this, Double.toString(myNewShape.Area()), Toast.LENGTH_LONG).show(); weak_from_this可能已经完成了。

答案 1 :(得分:5)

没有办法。考虑:

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不能被调用,是因为它的返回值还无法分配。这也不是因为它将永远不会被分配。这是因为它将在执行代码时分配以后。操作顺序是程序的运行时属性。您不能在编译时声明操作顺序,而在运行时完成。

答案 2 :(得分:4)

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

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进行条件编译),这样在运行时就不会受到性能损失。请注意noexcept

投掷的另一种方法是assert()