在学习C++ Primer Plus的过程中,遇到一个有趣的问题。
众所周知,类的私有变量是无法在类外直接访问的,只能通过类的成员函数访问。
且看下面一段代码:
class Stock
{
private:
double total_val;//这是私有的哦~
public:
Stock();//默认构造函数
Stock(const char* co, int n = 0, double pr = 0.0);
~Stock();//析构函数
const Stock& topval(const Stock& s)const;
};
可以看到total_val变量是类的私有变量。
const Stock& Stock::topval(const Stock& s)const
{
if (s.total_val > total_val)
{
return s;
}
else
{
return *this;
}
}
上面代码中,topval(const Stock& s)是类的一个成员函数,其参数是一个Stock类的引用。
有趣的事情发生了,在topval(const Stock& s)中能访问total_val变量是可以接受的,但是竟然可以访问到传入的另一个Stock类对象的私有数据s.total_val。
我们新建一个其他类,看看能否在Stock的成员函数中访问其私有数据。
class Test
{
private:
int port = 8080;
public:
const char* ip = "127.0.0.1";
};
然后修改Stock类,添加一个成员函数。
class Stock
{
private:
double total_val;
public:
Stock();//默认构造函数
Stock(const char* co, int n = 0, double pr = 0.0);
~Stock();//析构函数
const Stock& topval(const Stock& s)const;
const Stock& ftest(const Test& t)const;//添加这一行代码
};
在新添加的成员函数中进行测试如下:
const Stock& Stock::ftest(const Test& t)const
{
std::cout << t.ip;
std::cout << t.port;
return *this;
}
结果并不意外,
可以访问Test类对象的公有数据port,但是在访问Test类对象的私有数据ip时报错“无法引用”。
我们修改Test类的声明,使Stock成为Test类的一个友元类。
class Test
{
private:
int port = 8080;
friend class Stock;//添加这一行代码
public:
const char* ip = "127.0.0.1";
};
这时,测试函数便不再报错。
其实,我们咬文嚼字一下,书上的描述“类方法可以访问类的private组件”,其描述范围是“类”。因此,无论创建多少的类的对象,类的成员函数(无论调用对象是哪个)都可以访问到任一对象的私有数据。如果究其原因,应该是“同一个类的所有对象共享同一组类方法”。
总结:在类的成员函数中可以访问本类的私有数据,即使是通过函数参数传入的本类的另一个对象的私有数据,也可以正常访问,即“本类的私有数据”由所有本类的对象的私有数据组成。但是在A类中无法直接访问B类的私有数据,但可以通过友元类实现。