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,还允许用一个常量对象作为样本,来构造一个新的对象。


相关文章
|
22小时前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
12 4
|
2天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
11 4
|
24天前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
22 4
|
24天前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
18 1
|
24天前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
20 4
|
1月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
1月前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)
|
1月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
23 3
|
1月前
|
C++
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
C++番外篇——对于继承中子类与父类对象同时定义其析构顺序的探究
51 1
|
1月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
18 1