我最近遇到了让我感到惊讶的事情,对它进行一些澄清很高兴。
假设我有一个由A
组成的课程,其中包含以下内容:
#include "B.h"
class A {
private:
B* inst_b;
std::mt19937 mt_eng;
static void update_routine(double& _p, std::mt19937& _eng) {
// does stuff, not important here
}
public:
A() {
std::random_device rd;
mt_eng = std::mt19937(rd());
}
void updateP() {
inst_b->update_quantity(update_routine, mt_eng);
}
//...
};
和类B
如下:
#include <random>
class B {
protected:
double qty;
//...
public:
B() {
qty = 0.0;
}
void update_quantity(void(*fptr)(double&, std::mt19937&), std::mt19937& _eng) {
fptr(qty, _eng); // no error here
}
//...
};
现在我认为编译器会抱怨尝试在update_quantity
的主体中调用该函数,因为update_routine
的{{1}}是A
成员函数,因此我认为尝试从private
调用它会导致B
错误或类似的东西 - 即使它已作为函数指针传递。
在我的项目中,当我执行上述操作时,它会成功编译并执行 - 这是为什么?当然,对我来说非常有用,它确实 编译并运行但是我想了解为什么会这样。
P.S:如果这是重复的话,我表示歉意,如果是这种情况,请链接相关主题。答案 0 :(得分:2)
术语public和private(和protected)实际上只引用事物的名称 - 它是私有的名称update_routine
,只能解析为类范围内的实际函数。由于您只使用了班级范围内的名称,因此没有问题。
答案 1 :(得分:1)
它从A内部传递,在那里它是非常明显的。可见性不会改变功能的类型。
如果您尝试从A::update_routine
拨打B::update_quantity
,这将是非法的。但是A给了B地址并委托函数调用它。同时B不知道它收到的函数地址。
答案 2 :(得分:1)
class B {
protected:
double qty;
public:
B() {
qty = 0.0;
}
void update_quantity(void(*fptr)(double&, std::mt19937&), std::mt19937& _eng) {
fptr(qty, _eng); // no error here
}
};
上述代码中没有引用A
类。
您正在取消引用中的fptr
update_quantity
功能,但原型
对fptr
没有任何引用
A
类 - 所以没有特权违规
B级到A级。
update_routine
的地址可能会作为一个传递
函数指针参数 - 但A函数仍未直接编码在B类中,如所写。换句话说,如果函数指针只是一个参数,那么取消引用此函数指针参数不一定会导致类特权违规。
fptr
严格来说属于update_quantity
,并且不属于A类的一部分..