[英]Is there a way to make member function NOT callable from constructor?
I have member function (method) which uses 我有使用的成员函数(方法)
std::enable_shared_from_this::weak_from_this()
In short: weak_from_this
returns weak_ptr
to this . 简而言之:
weak_from_this
将weak_ptr
返回给此 。 One caveat is it can't be used from constructor. 一个警告是它不能从构造函数中使用。 If somebody would use my function from constructor of inherited class,
weak_from_this
inside it would return expired weak_ptr
. 如果有人会从继承类的构造函数中使用我的函数,
weak_from_this
里面会返回过期的weak_ptr
。 I guard against that with assertion checking that it's not expired, but it's a run-time check. 我通过断言检查它没有过期来防止这种情况,但这是一次运行时检查。
Is there a way to check against it at compile time? 有没有办法在编译时检查它?
I am afraid the answer is "no, it's not possible to protect against this at compile-time." 我担心答案是“不,在编译时不可能防止这种情况发生。” It's always difficult to prove a negative, but consider this: if it was possible to protect a function this way, it would probably have been done for
weak_from_this
and shared_from_this
in the standard library itself. 它总是很难证明一个消极的,但想想看:如果有可能保护功能这样的话,大概已经为做
weak_from_this
和shared_from_this
标准库本身。
No there is no way. 不,没有办法。 Consider:
考虑:
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
}
The thing is there is a reason you want to check for not calling shared_from_this
in the constructor. 问题是你有理由检查是否在构造函数中调用了
shared_from_this
。 Think about that reason. 想想那个理由。 It's not that
shared_from_this
cannot be called, it's because it's return value has no way of being assigned yet. 这不是
shared_from_this
不能被调用,这是因为它的返回值无法分配。 It is also not because it will never be assigned. 这也不是因为它永远不会被分配。 It's because it will be assigned later in the execution of the code.
这是因为它将在稍后的代码执行中分配。 Order of operation is a runtime property of your program.
操作顺序是程序的运行时属性。 You cannot assert at compile time for order of operation, which is done at runtime.
您无法在编译时断言操作顺序,这是在运行时完成的。
Not as such, but - if performance is not an issue, you could add a flag which indicates construction is complete, and use that to fail at run-time with such calls: 不是这样,但是 - 如果性能不是问题,您可以添加一个表示构造已完成的标志,并在运行时使用该标志进行此类调用:
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 };
}
You could also make these checks only apply when compiling in DEBUG mode (eg with conditional compilation using the preprocessor - #ifndef NDEBUG
) so that at run time you won't get the performance penalty. 您还可以使这些检查仅在DEBUG模式下编译时适用(例如,使用预处理器进行条件编译 -
#ifndef NDEBUG
),这样在运行时您将不会受到性能损失。 Mind the noexcept
s though. 但请注意
noexcept
。
An alternative to throwing could be assert()
'ing. 抛出的替代方法可以是
assert()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.