C++访问类的私有成员变量的方法(友元函数、友元类)

本文探讨了C++中友元函数的应用场景,包括友元类、友元函数及不同类型的成员函数作为友元的情况。同时,详细解释了哪些成员函数可以声明为常量成员函数,以及构造函数、析构函数等为何不能声明为常量成员函数的原因。此外,文中还讨论了拷贝构造函数参数使用引用的原因。

// win32Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

class A
{
public:
 A(){;}
 ~A(){;}

public:
 int fun(A& one)
 {
  //表达式1:错误
  //return one.fun(this);
  //表达式2:错误,cannot convert parameter 1 from 'class A *const ' to 'class A &'
  //m_iX = fun(this);
  //return m_iX;
  //表达式3:正确
  int* const pX = &one.m_iX;
 }

private:
 int m_iX;
 //const B& b1;//正确,可以这样声明,类的成员变量可以是常引用,但是在构造函数必须初始化
 //B& b2;//正确,可以这样声明,类的成员变量可以是常引用,但是在构造函数必须初始化
};

class B
{
public:
 B();
 ~B();
 
public:
 int Get(B& b)
 {
  return b.m_iY;//正确,类的内部可以直接访问私有变量
 }

 int Get()
 {
  return m_pOne->m_iY;//正确,类的内部可以直接访问私有变量
 }

public:
 friend int global_getB(B& b);//定义成友元函数

private:
 int m_iY;
 B* m_pOne;
};

int global_getB(B& b)//全局函数
{
 return b.m_iY;//正确,友元函数可以直接访问私有变量
}

class C
{
private:
 C(){}
 ~C(){}

public:
 friend class D;
};

class D
{
public:
 D(){}
 ~D(){}

public:
 C* GenFun()
 {
  return new C();//可以通过友元类的方式创建对象C
 }
};

//C++访问类的私有成员变量的方法:
//方法1:set/get接口
class E
{
 int i;

public:
 E()
 {
  i = 50;
 }
 
 int get() const {return i;}
 void set(int k) {i = k;}
};

//方法2:友元类
class F
{
 int i;

public:
 F()
 {
  i = 50;
 }
 
 friend class G;
};

class G
{
public:
 F f;
 int get()
 {
  return f.i;
 }
};

//方法3:友元函数
class H
{
 int i;

public:
 friend int global_getH(H& h);
};

int global_getH(H& h)
{
 return h.i;
}

int main(int argc, char* argv[])
{
 //B& b3;//错误,不可以这样定义,必须初始化
 //C c;//错误,类c的构造函数是私有的,必须通过静态函数或者友元的方法来实例化对象
 return 0;
}

两道问答题:

//在声明类中的构造函数、析构函数、纯虚函数、静态成员函数、非静态的成员函数以及全局函数作为类的友元函数时,哪些可以是常量成员函数?
//只有纯虚函数、非静态的成员函数可以是常量成员函数。
//(这题有点问题,析构函数可以是纯虚函数,但不能是常量函数)
//1、声明带有 const 关键字的成员函数指定,函数是 “只读”函数,在它被调用的时候不会修改对象。一个常数成员函数不能修改任何非静态数据成员或调用不是常数的任何成员函数。
//若要声明常数成员函数,请在参数列表的右括号后放置const关键字。声明和定义中均要求该const关键字。
//2、构造函数和析构函数为了生成和释放成员变量,显然不能是const。
//3、静态成员函数不能是常量成员函数的原因:
//(1)const成员函数是包含this指针的。这明显不被static函数允许。
//(2)因为static成员不是任何对象的组成部分,所以static成员不能被声明为const,毕竟将成员声明为const就是承诺不会修改该函数所属对象。
//(3)const针对对象才有意义。const是基于对象的;static 是基于类的。
//4、全局函数作为类的友元函数时,它是定义在类外的普通函数,并不属于类的成员函数。

//通常类A的拷贝构造函数的原型写为A(const A&);,请问为什么参数一定要使用引用形式?使用const修饰符除了可以防止修改传递给构造函数的实参外,还有什么作用?
//A(const A& one ).当调用此拷贝构造函数时,需将参数压栈,若不使用&,就需要在栈内创建一个one的副本,而这需要用拷贝构造函数。这样就会形成递归调用。
//使用const,还允许用一个常量对象作为样本,来构造一个新的对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值