class A {
public:
A() {auto tmp = &A::foo;}
protected:
void foo() {}
};
class B : public A {
public:
B() {auto tmp = &A::foo;}
};
类A
编译没问题。类B
产生编译错误:
' A :: foo的' :无法访问在类' A'
中声明的受保护成员
为什么这样,理由是什么?有没有办法绕过这个(如果我需要回调指针,std::function
等)?
答案 0 :(得分:4)
为什么这是什么理由?
通常,派生类只能访问同一派生类的受保护成员,而不能访问基类本身或具有相同基类的任意类。因此,B
可以通过A
访问B
的受保护成员,但不能直接通过A
访问。
有没有办法规避这个?
继承的成员也是B
的成员,可以这样访问:
auto tmp = &B::foo;
答案 1 :(得分:2)
如果您能够指向A::foo
,则可以使用它来对foo
类型的对象或A
类型的对象调用C
。 {1}}:
A
相反,请指向class B : public A {
public:
void xx(A a) { auto tmp = &A::foo; a.*tmp(); } // illegal
}
;这很好,因为你只能在类型为B::foo
的对象上使用它。
答案 2 :(得分:1)
大概是为了安全。如果你能得到一个指向那个成员的指针,并且绝对没有任何警报响的话就把它交给任何人,这将是有风险的。
这是 a 解决方法(其他人可能会更清楚):
class A {
public:
A() {auto tmp = &A::foo;}
protected:
void foo() {}
};
class B : public A {
public:
B() {auto tmp = &B::foo;}
};
编辑 - 认为你可能需要使用A :: foo,但你甚至不需要它。没有工作。参见:
答案 3 :(得分:1)
您可以通过B
访问它,即:
class B : public A {
public:
B() {auto tmp = &B::foo;}
};
您无法从&A::Foo
外部访问B
,因为它受到保护,但您可以通过继承(因为Foo
成为{{1}的成员通过继承),即通过调用B