C++友元

简介: C++友元

C++友元

C++友元是用friend关键修饰的函数或者类,友元用来打破类封装(忽视权限限定)

  • 友元并不是说直接访问数据成员,友元只是提供一个场所赋予对象具有打破权限限定
  • 友元函数
  • 友元类
  • 友元函数和友元类不属于当前类,实现函数或者类不需要类名限定

友元函数

  • 普通函数成为类的友元函数
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
  MM(string name, int age, int num) :name(name), age(age), num(num) {}
  void print();
  //友元函数
  friend void visitedData();
  friend void visited(MM mm);
protected:
  int num;
private:
  int age;
  string name;
};
void MM::print() 
{
  cout << name << "\t" << age << "\t" << num << endl;
}
//友元函数
void  visitedData() 
{
  //name = "ILoveyou";   不是直接访问,赋予对象的具有这样权限
  //创建对象的无视权限
  MM  mm("girl", 18, 1001);
  cout << mm.name << "\t" << mm.age << "\t" << mm.num << endl;
  MM* p = new MM("new", 28, 1002);
  cout << p->name << "\t" << p->age << "\t" << p->num << endl;
}
void visited(MM mm) 
{
  cout << mm.name << "\t" << mm.age << "\t" << mm.num << endl;
}
int main() 
{
  MM girl("girl", 19, 1002);
  //girl.name="name";     //类外只能访问public
  girl.print();
  visitedData();
  visited(girl);
  return 0;
}
  • 以另一个类的成员函数为友元函数
#include <iostream>
#include <string>
using namespace std;
//前向声明
class A;
class B
{
public:
  B(int b) :b(b) {}
  void printA(A object);
private:
  int b;
};
class A 
{
public:
  A(int a) :a(a) {}
  friend void B::printA(A object);
private:
  int a;
};
void B::printA(A object)
{
  cout << object.a << endl;
}
int main() 
{
  B b(111);
  A a(222);
  b.printA(a);
  return 0;
}

//A 以B的成员函数为友元函数,B又以A类的成员函数为友元,如果存在这种需求,代码设计有问题,C++允许这种关系

友元类

#include <iostream>
#include <string>
using namespace std;
class MM 
{
  friend class Boy;   //声明boy类是MM友元类
public:
  MM(string name) :name(name) {}
private:
  string name;
};
//友元类中,MM类的对象无视权限
class Boy 
{
public:
  Boy() :mm("mm")
  {
    pObject = new MM("Object");
  }
  void print() 
  {
    cout <<"访问私有属性:" << mm.name << endl;
    cout << "访问私有属性:" << pObject->name << endl;
    MM* pMM = new MM("new");
    cout << "访问私有属性:" << pMM->name << endl;
  }
private:
  MM mm;
  MM* pObject;
};
//互为友元类--->知道有这么回事就行,不需要自己写这样代码
class A 
{
public:
  friend class B;
  void printA();
private:
  string a_name="A";
};
class B
{
public:
  friend class A;
  void printB() 
  {
    A a;
    cout << a.a_name << endl;
  }
private:
  string b_name="B";
};
void A::printA() 
{
  B b;
  cout << b.b_name << endl;
}
int main() 
{
  Boy boy;
  boy.print();
  B b;
  b.printB();
  A a;
  a.printA();
  return 0;
}

小试牛刀

//自己写个友元案例,测试打破权限这个功能即可

C++类型转换

构造的方式做转换

#include <iostream>
using namespace std;
int main() 
{
  int num = 1.11;
  cout << num << endl;
  int cnum = (int)1.11;
  cout << cnum << endl;
  int cppnum = int(1.22);   //C++强制类型转换
  cout << cppnum << endl;
  return 0;
}

static_cast类型转换

类似C语言的强制类型转换,按照C++的说法 比C语言的更为安全

  • 基本数据类型的强制转换
  • 空指针转换目标类型指针
  • 不能操作带const属性的类型
//static_cast<要转换的类型>(要转换目标)
//要转换的类型: 数据类型
//要转换目标  可以是表达式,或者常量,都可以
#include <iostream>
using namespace std;
void test_static_cast()
{
  //No.1 基本数据类型的强制转换
  int num = static_cast<int>(1.111);
  //No.2 空类型指针的转换
  double* pD = new double(1.11);
  void* pVoid = static_cast<void *>(pD);
  //No.3 不能做const属性的类型的转换
  //增加const属性
  //不能去掉const属性
  int number = 11;
  const int cNum = static_cast<const int >(number);
  const int ccNum = number;
  const int data = 1;
  int* pData = (int *)(&data);        //C语言强制类型转换
  //int* pcData = static_cast<int*>(&data);   //错误
}
int main() 
{
  test_static_cast();
  return 0;
}

const_cast类型转换

  • 去掉const属性(提供一个可以修改接口去操作const数据类型)
  • 加上const属性(用的少一点)
#include <iostream>
using namespace std;
class Str 
{
public:
  //去掉const属性
  Str(const char* str) :str(const_cast<char*>(str)) {}
  void print() 
  {
    cout << str << endl;
  }
private:
  char* str;
};
void test_const_cast() 
{
  //增加const属性
  const int data = 1;
  int* pData = const_cast<int*>(&data);
  *pData = 1001;    //不会作用到const变量,只是单纯提供一个接口
  cout <<"data:"<< data << endl;
  cout << "*pData:" << *pData << endl;
  cout << &data << endl;
  cout << pData << endl;
  Str str("ILoveyou");    //错误,C++对于const要求更为严格
  str.print();
  char sstr[20] = "ILoveyoud";
  Str str2(sstr);
  str2.print();
    //3.引用类型
  Test test;
  const Test& c_test = test;
  //c_test.print();   //常属性的对象只能调用常成员函数
  Test& m_test = const_cast<Test&>(c_test);
  m_test.print();
}
int main() 
{
  test_const_cast();
  return 0;
}

reinterpreat_cast类型转换

把指针转换为一个整数,又可以把整数转换为一个指针,指针的效果依然有效(认识知道有这么回事即可)

#include <iostream>
using namespace std;
int Max(int a, int b) 
{
  return a > b ? a : b;
}
//官方案例
unsigned short Hash(void* p) {
  unsigned int val = reinterpret_cast<unsigned int>(p);
  return (unsigned short)(val ^ (val >> 16));
}
void test_reinterpret_cast() 
{
  int* p = reinterpret_cast<int*>(0);   //p=nullptr;
  //官方案例
  int a[20];
  for (int i = 0; i < 20; i++)
    cout << Hash(a + i) << endl;
  //允许将任何指针转换为任何其他指针类型。 也允许将任何整数类型转换为任何指针类型以及反向转换
  int* num = reinterpret_cast<int*>(Max); //把函数地址转换为int类型的数字
  cout << *num << endl;
  auto pMax = reinterpret_cast<int(*)(int, int)>(num);
  cout << "max:" << pMax(1, 2) << endl; 
}
int main() 
{
  test_reinterpret_cast();
  return 0;
}
目录
相关文章
|
5月前
|
程序员 C++
29 C++ - 友元
29 C++ - 友元
27 0
|
1月前
|
C++
38友元
38友元
10 0
|
2月前
|
C++
【c++】友元
【c++】友元
【c++】友元
|
8月前
|
算法 C语言 C++
|
6月前
|
C++
C++ 友元
C++ 友元
25 0
|
8月前
|
安全 编译器 C++
C++友元函数和友元类
在 C++ 中,一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。现在,我们来介绍一种例外情况——友元(friend)。 借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。 friend 的意思是朋友,或者说是好友,与好友的关系显然要比一般人亲密一些。我们会对好朋友敞开心扉,倾诉自己的秘密,而对一般人会谨言慎行,潜意识里就自我保护。 在 C++ 中,这种友好关系可以用 friend 关键字指明,中文多译为“友
53 0
|
11月前
|
C++
静态成员,友元函数,友元类
🐰静态数据成员 🌸静态数据成员的声明: 🌸静态数据成员的初始化: 🌸静态数据成员的访问: 🐰静态成员函数 🌸静态成员函数的声明 🌸静态数据成员函数的访问 🐰友元函数 友元函数的声明 🐰 友元类