问题
This code snippet demonstrating changing class member access came from IBM.
struct A {
protected:
int y;
public:
int z;
};
struct B : private A { };
struct C : private A {
public:
using A::y;
using A::z;
};
struct D : private A {
protected:
using A::y;
using A::z;
};
struct E : D {
void f() {
y = 1;
z = 2;
}
};
struct F : A {
public:
using A::y;
private:
using A::z;
};
int main() {
B obj_B;
// obj_B.y = 3;
// obj_B.z = 4;
C obj_C;
obj_C.y = 5;
obj_C.z = 6;
D obj_D;
// obj_D.y = 7;
// obj_D.z = 8;
F obj_F;
obj_F.y = 9;
obj_F.z = 10;
}
According to the article, modifying obj_F.z
is allowed because the using
declaration in the F
class does not take effect, and therefore, F::z
is still public
.
However, when I plug this into Compiler Explorer, it does not compile, saying F::z
is private
. What's going on here?
回答1:
The article seems wrong. It says,
You cannot restrict the access to x with a using declaration.
But I can't find such statement from the standard. [namespace.udecl]/19
A synonym created by a using-declaration has the usual accessibility for a member-declaration.
[ Example:
class A { private: void f(char); public: void f(int); protected: void g(); }; class B : public A { using A::f; // error: A::f(char) is inaccessible public: using A::g; // B::g is a public synonym for A::g };
— end example ]
Even the example is increasing the accessibility, but the standard doesn't say accessibility can't be restricted.
PS: Both clang and gcc fail to compile the code.
来源:https://stackoverflow.com/questions/61928364/can-you-use-using-to-redeclare-a-public-member-in-base-class-as-private-in-deriv