C++之面向对象(下)(二)

简介: C++之面向对象(下)(二)

3.友元类

1.友元类的引入

如果想要在一个类中访问另一个类的成员,就需要将这个类声明为另一个类的友元类。

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

2.友元类的说明

  • 友元关系是单向的,不具有交换性;
    比如上述Time类Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
  • 友元关系不能传递
    如果C是B的友元, B是A的友元,则不能说明C时A的友元。
  • 友元关系不能继承
class Time
{
  friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
public:
  Time(int hour = 0, int minute = 0, int second = 0)
    : _hour(hour)
    , _minute(minute)
    , _second(second)
  {}
private:
  int _hour;
  int _minute;
  int _second;
};
class Date
{
public:
  Date(int year = 1900, int month = 1, int day = 1)
    : _year(year)
    , _month(month)
    , _day(day)
  {}
  void SetTimeOfDate(int hour, int minute, int second)
  {
    // 直接访问时间类私有的成员变量
    _t._hour = hour;
    _t._minute = minute;
    _t._second = second;
  }
private:
  int _year;
  int _month;
  int _day;
  Time _t;
};

四、内部类

1.概念

如果一个类定义在另一个类里面。则这个类就叫做另一个类的内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问它,外部类对内部类没有任何特殊的访问权限(即,和其他类或对象的访问限制没有区别)。

但是,内部类天生就是外部类的友元类。友元类的概念参照上文,内部类可以通过外部类的对象参数访问外部类的所有成员,但是外部类不是内部类的友元。

2.特性

  1. 内部类可以定义在外部类的publicprotectprivate的限制中;
  2. 内部类可以直接访问外部类的static成员,而不需要借助外部类的类名或者外部类的对象;
  3. sizeof(外部类)=外部类,和内部类没有关系。
    观察下面代码:
class A
{
private:
  static int k;
  int h = 2;
public:
  class B // B天生就是A的友元,但是A不是B的友元
  {
  public:
    void func(const A& a)
    {
      cout << k << endl;//可以访问
      cout << a.h << endl;//可以访问
    }
  };
};
int A::k = 1;
int main()
{
  A::B b;
  b.func(A());
  return 0;
}

运行结果:

五、匿名对象

一般情况下,我们定义一个对象都会给它一个对应的一个名字。特殊的,我们可以定义一个没有名字的对象——匿名对象。

这种对象的生命周期只有它定义所在的那一行,运行到下一行就会销毁,属于一次性的对象,所以不需要命名。

观察以下代码:

class A
{
public:
  A(int a = 0)
    :_a(a)
  {
    cout << "A(int a)" << endl;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
private:
  int _a;
};
class Solution {
public:
  int Sum_Solution(int n) {
    //...
    return n;
  }
};
int main()
{
  A aa1;
  // 不能像下面这一行这样定义对象,因为编译器无法识别它是一个函数声明,还是对象定义
  //A aa1();
  // 我们可以像下一行这样定义匿名对象,匿名对象的特点是不用取名字,但是他的生命周期只有这一行,到下一行他就会自动调用析构函数
  A();
  A aa2(2);
  // 匿名对象在这样场景下就会好用(只需要使用一次,就可以进行销毁)
  Solution().Sum_Solution(10);
  return 0;
}

六、拷贝构造对象时编译器的优化

上文中介绍了一种拷贝构造对象时编译器的优化,接下来我们了解还有哪些拷贝构造对象时优化。

传参传返回值的过程中,一般编译器会做一些优化,减少对象的拷贝,这个在一些场景下还是非常有用的。

一般编译器会在不影响程序结果的情况下对程序进行一些优化,观察下面代码,了解这几种可以优化的情况:

class A
{
public:
  A(int a = 0)
    :_a(a)
  {
    cout << "A(int a)" << endl;
  }
  A(const A& aa)
    :_a(aa._a)
  {
    cout << "A(const A& aa)" << endl;
  }
  A& operator=(const A& aa)
  {
    cout << "A& operator=(const A& aa)" << endl;
    if (this != &aa)
    {
      _a = aa._a;
    }
    return *this;
  }
  ~A()
  {
    cout << "~A()" << endl;
  }
private:
  int _a;
};
void f1(A aa)
{}
A f2()
{
  A aa;
  return aa;
}
int main()
{
  // 传值传参
  A aa1;
  f1(aa1);
  cout << endl;
  // 传值返回
  f2();
  cout << endl;
  // 隐式类型,连续构造+拷贝构造->优化为直接构造
  f1(1);
  // 一个表达式中,连续构造+拷贝构造->优化为一个构造
  f1(A(2));
  cout << endl;
  // 一个表达式中,连续拷贝构造+拷贝构造->优化一个拷贝构造
  A aa2 = f2();
  cout << endl;
  // 一个表达式中,连续拷贝构造+赋值重载->无法优化
  aa1 = f2();
  cout << endl;
  return 0;
}

七、再次理解类和对象

类是对某一类实体(对象)来进行描述的,描述该对象具有那

些属性,那些方法,描述完成后就形成了一种新的自定义类型,采用该自定义类型就可以实例化出具体的对象。


总结

以上就是今天要讲的内容,本文介绍了构造函数中的初始化列表、隐式类型转换、类的静态成员、友元、内部类、匿名对象以及编译器对拷贝构造的优化等相关概念。本文作者目前也是正在学习C++相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。

最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!

相关文章
|
1月前
|
安全 程序员 编译器
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则
81 11
|
2月前
|
存储 安全 编译器
【C++核心】一文理解C++面向对象(超级详细!)
这篇文章详细讲解了C++面向对象的核心概念,包括类和对象、封装、继承、多态等。
27 2
|
1月前
|
存储 编译器 C语言
【C++】初识面向对象:类与对象详解
【C++】初识面向对象:类与对象详解
|
6月前
|
算法 Java 程序员
【C++专栏】C++入门 | 类和对象 | 面向过程与面向对象的初步认识
【C++专栏】C++入门 | 类和对象 | 面向过程与面向对象的初步认识
53 0
|
3月前
|
存储 安全 数据处理
【C++】C++ 超市会员卡管理系统(面向对象)(源码+数据)【独一无二】
【C++】C++ 超市会员卡管理系统(面向对象)(源码+数据)【独一无二】
|
3月前
|
算法 数据可视化 C++
【C++】C++ 学生信息管理系统(源码+面向对象)【独一无二】
【C++】C++ 学生信息管理系统(源码+面向对象)【独一无二】
|
4月前
|
存储 开发框架 Java
|
5月前
|
算法 编译器 C语言
C++进阶之路:深入理解编程范式,从面向过程到面向对象(类与对象_上篇)
C++进阶之路:深入理解编程范式,从面向过程到面向对象(类与对象_上篇)
70 3
|
4月前
|
Java C++ iOS开发
|
5月前
|
C++
C++ 是一种面向对象的编程语言,它支持对象、类、继承、多态等面向对象的特性
C++ 是一种面向对象的编程语言,它支持对象、类、继承、多态等面向对象的特性