C++ 引用和好友类的意外行为
使用friend关键字和引用时出现意外行为。代码如下:C++ 引用和好友类的意外行为,c++,C++,使用friend关键字和引用时出现意外行为。代码如下: #include <iostream> class Modifier; class A{ private: int _a; friend Modifier; }; class B : public A {}; class Modifier { public: void f(A& i) { i._a = 10; std::cout << i._a << std::
#include <iostream>
class Modifier;
class A{
private:
int _a;
friend Modifier;
};
class B : public A {};
class Modifier
{
public:
void f(A& i) { i._a = 10; std::cout << i._a << std::endl; }
};
int main()
{
Modifier m;
B b;
m.f(b);
}
// Output
// 10
#包括
类修饰语;
甲级{
私人:
国际组织;
朋友修饰语;
};
B类:公共A{};
类修饰语
{
公众:
空位f(A&i){i.\u A=10;标准::cout
B应该不能修改变量a
\u a
和包含它的对象是非常量的,因此可以修改\u a
。声明成员私有不会阻止修改变量。访问说明符只影响可访问变量名称的范围
类B
不修改变量\u a
。修改\u a
变量(变量B
的a
基本子对象的成员)的是修饰符::f
.Modifier
是类a
的朋友,因此Modifier
的成员函数可以访问a
的私有声明名称。具有访问权限意味着它可以使用名称a:\u a
B应该不能修改变量a
\u a
和包含它的对象是非常量的,因此可以修改\u a
。声明成员私有不会阻止修改变量。访问说明符只影响可访问变量名称的范围
类B
不修改变量\u a
。修改\u a
变量(变量B
的a
基本子对象的成员)的是修饰符::f
Modifier
是类a
的朋友,因此Modifier
的成员函数可以访问a
的私有声明名称。具有访问权限意味着它可以使用名称a::\u a
B
已经无法修改\u a
,因为它在B
中声明为私有。它处于启用状态可在A
中轻松访问。如果需要从B
中读取\u A
,请使用受保护的getter:
class A {
protected:
auto get_a() const { return _a; }
private:
int _a;
friend Modifier;
};
B
已经无法修改\u a
,因为它在B
中声明为私有。它只能在a
中访问。如果需要从B
读取\u a
,请使用受保护的getter:
class A {
protected:
auto get_a() const { return _a; }
private:
int _a;
friend Modifier;
};
friend类可以访问声明为friend的其他类的私有和受保护成员。因此,\u A
可以通过类Modifier
的任何方法进行修改。但是,B
不能修改\u A
,因为它在类A
中定义为私有。例如,如果您想导入在类B
中删除方法f
,则会得到编译器错误,该错误表示'int A::_A'是私有的
class B : public A {
void f(A& i) { i._a = 10; std::cout << i._a << std::endl; }
};
B类:公共A{
无效f(A&i){i._a=10;std::coutafriend类可以访问声明为friend的其他类的私有和受保护成员。因此,\u a
可以通过类修改器的任何方法进行修改。但是,B
不能修改\u a
,因为它在类a
中定义为私有例如,如果您在类B
中实现方法f
,那么您将得到编译器错误,该错误表示'int A::_A'是私有的
class B : public A {
void f(A& i) { i._a = 10; std::cout << i._a << std::endl; }
};
B类:公共A{
无效f(A&i){i._a=10;std::cout但您没有将B
对象传递给Modifier::f
,而是传递对a
对象的引用。函数Modifier::f
对B
一无所知。B不应该能够修改变量_a.-为什么?作为一种可能的解决方案,创建一个f
重载,使其引用B
,并将其标记为已删除。即void f(B const&)=delete;
。访问控制仅使用被访问对象的静态类型(出现在引用参数声明中的类型)。我不使用对象的动态类型(最派生的类型)你认为Modifier
不能访问\u a
,因为B
是从a
私下继承来的吗?如果是这样,你应该在问题中包含它。我花了一段时间,我仍然不确定你为什么认为\u a
不能访问,但你是不将B
对象传递给Modifier::f
,而是传递对a
对象的引用。函数Modifier::f
对B
一无所知。B应该不能修改变量_a。-为什么?作为一种可能的解决方案,创建一个引用B
的f
重载>,并将其标记为已删除。例如,void f(B const&)=delete;
。访问控制仅使用访问对象的静态类型(出现在引用参数声明中的类型)。我不使用对象的动态类型(最派生的类型)你认为Modifier
不能访问\u a
,因为B
是从a
私下继承的吗?如果是这样的话,你应该把它包括在问题中。我花了一段时间,我仍然不确定你为什么认为\u a
不能访问我同意t是修饰符::f修改了a,但我们看a到i,它是B的一个实例。编译器是否允许函数绕过私有关键字?@BleakMidWinterModifier
是友元,因此它有访问权。友元声明“绕过私有关键字”如果你想这样说的话。\u a
是否在B
的基础内是无关紧要的。我同意修改a的是修饰符::f,但我们看看B的一个实例_a到I。编译器是否允许函数绕过私有关键字?@blakmidw