我有使用
的成员函数(方法)std::enable_shared_from_this::weak_from_this()
简而言之:weak_from_this
返回weak_ptr
到 this 。一个警告是它不能从构造函数中使用。
如果有人使用继承的类的构造函数中的函数,则其中的weak_from_this
将返回过期的weak_ptr
。我通过断言检查它是否未到期来进行防范,但这是运行时检查。
有没有一种方法可以在编译时进行检查?
答案 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()
。