C++中的成员函数作为另一个类的友元函数,为什么c1.a1 = 1还是报错,访问不了对方私有成员?
class Class1
{
friend void Class2::test();
public:
int a;
private:
int a1;
};
class Class2
{
public:
void test()
{
Class1 c1;
c1.a = 1;
c1.a1 = 1; //这句话会报错,说对a1没有访问权限
}
};
因为c++,要用到一个类型,必须在这个类型完整声明后才能使用。你在class1声明class2的成员函数是自己的友元,就必须要求class2的声明必须在class1之前.而class2的成员函数是class1的友元且要访问class1的成员,则class2 的成员函数必须声明在class1之后
所以代码应该如此
class Class2
{
public:
void test();
};
class Class1
{
friend void Class2::test();
public:
int a;
private:
int a1;
};
void Class2::test()
{
Class1 c1;
c1.a = 1;
c1.a1 = 1; //这句话会报错,说对a1没有访问权限
}
该问题出现的原因是:友元关系不具有传递性,即如果A是B的友元,B是C的友元,那么A不一定是C的友元。在这种情况下,子类对父类的友元不具有访问父类私有成员的权限。
解决该问题的方法可以通过修改代码,将成员变量的访问权限进行改变,或者通过添加新的友元来解决。
一种可能的解决方案是,将父类中需要访问的成员变量改为protected类型,这样子类就可以直接访问父类中的这些成员变量。另外,如果子类需要访问其他类的成员变量,可以在其他类中添加一个新的友元函数来实现。
举一个具体的例子,假设我们有以下的代码:
class ClassA {
private:
int a1;
int a2;
public:
friend void ClassB::modifyA(ClassA& obj);
};
class ClassB {
private:
int b1;
int b2;
public:
void modifyA(ClassA& obj) {
obj.a1 = 1; // 在这里访问a1,会报错
}
};
class ClassC : public ClassA {
private:
int c1;
public:
friend void ClassD::modifyC(ClassC& obj);
};
class ClassD {
private:
int d1;
int d2;
public:
void modifyC(ClassC& obj) {
obj.a2 = 2; // 在这里访问a2,不会报错
}
};
在这个例子中,ClassB是ClassA的友元类,可以访问ClassA中的私有成员;ClassD是ClassC的友元类,可以访问ClassC中的私有成员。但是,当我们尝试在ClassB中修改ClassA中的成员变量时,会报错提示无法访问私有成员。
为了解决这个问题,我们可以将ClassA中的成员变量改为protected类型,以便能够在子类中访问:
class ClassA {
protected: // 将私有成员改为protected
int a1;
int a2;
public:
friend void ClassB::modifyA(ClassA& obj);
};
class ClassB {
private:
int b1;
int b2;
public:
void modifyA(ClassA& obj) {
obj.a1 = 1; // 在这里访问a1,不会报错
}
};
class ClassC : public ClassA {
private:
int c1;
public:
friend void ClassD::modifyC(ClassC& obj);
};
class ClassD {
private:
int d1;
int d2;
public:
void modifyC(ClassC& obj) {
obj.a2 = 2; // 在这里访问a2,不会报错
}
};
这样,我们就可以成功地访问ClassA的私有成员了。不过,需要注意的是,将私有成员改为protected类型会破坏封装性,增加代码的耦合性和安全性风险,因此需要根据具体情况进行权衡。
你试试看把a1放在public中
a1是个局部变量,这跟友元函数哪有一毛钱关系