有没有办法让成员函数不能从构造函数中调用?
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_ptr
到 this。一个警告是它不能从构造函数中使用。
如果有人在继承 class、weak_from_this
的构造函数中使用我的函数,它会 return 过期 weak_ptr
。我通过断言检查它是否未过期来防止这种情况,但这是 运行 次检查。
有没有办法在编译时检查它?
恐怕答案是 "no, it's not possible to protect against this at compile-time." 总是很难证明是否定的,但考虑一下:如果有可能以这种方式保护功能,它可能已经完成了 weak_from_this
和 shared_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
),这样在 运行 时您就不会受到性能损失.不过请注意 noexcept
s。
投掷的替代方法是 assert()
'ing。
我有使用
的成员函数(方法)std::enable_shared_from_this::weak_from_this()
简而言之:weak_from_this
returns weak_ptr
到 this。一个警告是它不能从构造函数中使用。
如果有人在继承 class、weak_from_this
的构造函数中使用我的函数,它会 return 过期 weak_ptr
。我通过断言检查它是否未过期来防止这种情况,但这是 运行 次检查。
有没有办法在编译时检查它?
恐怕答案是 "no, it's not possible to protect against this at compile-time." 总是很难证明是否定的,但考虑一下:如果有可能以这种方式保护功能,它可能已经完成了 weak_from_this
和 shared_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
),这样在 运行 时您就不会受到性能损失.不过请注意 noexcept
s。
投掷的替代方法是 assert()
'ing。