lesson3-C++类和对象(下)(二)

简介: lesson3-C++类和对象(下)(二)

lesson3-C++类和对象(下)(一)+https://developer.aliyun.com/article/1393914

概念

  • 声明为static的类成员称为类的静态成员。
  • static修饰的成员变量,称之为静态成员变量;
  • 用static修饰的成员函数,称之为静态成员函数
  • 静态成员变量一定要在类外进行初始化。

实现一个类,计算程序中创建出了多少个类对象。

class A
{
public:
  A()
  {
    _count++;
  }
  A(const A& a)
  {
    _count++;
  }
  static int Get_count()
  {
    return _count;
  }
private:
  static int _count;
};
//这里才是_count的定义
int A::_count = 0;
void func(A a)
{
  //...
}
int main()
{
  A a;
  A b(a);
  func(a);
  cout << A::Get_count() << endl;
  return 0;
}

结果为3。

特性

  • 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区,所以在使用时要加作用域限定符,比如:A::Get_count()
  • 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明,比如:int A::_count = 0;
  • 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
  • 静态成员函数没有隐藏的this指针,不能访问任何非静态成员.
  • 静态成员也是类的成员,受publicprotectedprivate 访问限定符的限制

友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以

友元不宜多用。

友元分为:友元函数友元类

友元函数

我们现在可以去尝试重载operator<<运算符重载了。

如果我们将这个重载写在类体内,那么必然会有this指针去占到参数的第一个位置,那么我们再调用cout时流插入流入的方向就变成流向对象了,看例子:

#include <iostream>
using namespace std;
class Date
{
public:
  Date(int year = 2023, int month = 11, int day = 2)
  {
    _year = year;
    _month = month;
    _day = day;
  }
  void print()
  {
    cout << _year << "-" << _month << "_" << _day << endl;
  }
  ostream& operator<<(ostream& out)
  {
    out << _year << "-" << _month << "-" << _day;
    return out;
  }
private:
  int _year;
  int _month;
  int _day;
};
int main()
{
  Date a;
  a << cout;
}

这样重载<<运算符是不是很别扭,非常奇怪,所以注定了我们要将他重载到类外,也就是全局,

那么我们将其写在全局后,又因为这几个成员变量都是私有的,我们在类外无法访问到,我们当然可以写他们的Get函数得到他们的值,但是这样比较麻烦,而且C++不喜欢这样做,java才喜欢,C++会去搞一个友元函数。

直接看用法。

#include <iostream>
using namespace std;
class Date
{
    //在函数前加friend表示是友元函数,虽然我们将其声明在类内,但这个函数不属于类
  friend ostream& operator<<(ostream& out, const Date& d);
public:
  Date(int year = 2023, int month = 11, int day = 2)
  {
    _year = year;
    _month = month;
    _day = day;
  }
  void print()
  {
    cout << _year << "-" << _month << "_" << _day << endl;
  }
private:
  int _year;
  int _month;
  int _day;
};
ostream& operator<<(ostream& out, const Date& d)
{
  out << d._year << "-" << d._month << "_" << d._day << endl;
  return out;
}
int main()
{
  Date a;
  cout << a;
}

友元函数可以直接访问类的私有成员,它是定义在类外部普通函数,不属于任何类,但需要在

类的内部声明,声明时需要加friend关键字。

这样我们重载的函数成为了Date类的友元函数,就可以访问Date私有的成员变量。

友元类

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

我们举例说明,看代码:

#include <iostream>
using namespace std;
class Date
{
  friend class Time;
public:
  Date(int year = 2023, int month = 11, int day = 2)
  {
    _year = year;
    _month = month;
    _day = day;
  }
  void print() const
  {
    cout << _year << "-" << _month << "_" << _day << endl;
  }
private:
  int _year;
  int _month;
  int _day;
};
class Time
{
public:
  Time(int hour = 11, int minute = 54, int second = 0)
    :_hour(hour)
    ,_minute(minute)
    ,_second(second)
  {}
  void Print_Date_Time() const
  {
    cout << _d._year << "-" << _d._month << "-" << _d._day;
    cout << ":";
    //cout << _hour << "-" << _minute << "-" << _second << endl;
    printf("%d-%d-%02d\n", _hour, _minute, _second);
  }
private:
  int _hour;
  int _minute;
  int _second;
  Date _d;
};
int main()
{
  Time t;
  t.Print_Date_Time();
}

我们要注意Time是Date的友元,Time可以访问Date的私有的成员变量,但是Date不能访问Time私有的成员变量,有句话说的好,我把你当朋友,但是你不一定把我当朋友,就是这个道理。

内部类

首先说明C++中很少使用内部类,java是喜欢使用内部类的,我们只需要明白他的语法,能够看懂,明白需要注意的地方就好,很少使用内部类。

#include <iostream>
using namespace std;
class A
{
public:
  A()
  {
    _count++;
  }
  A(const A& a)
  {
    _count++;
  }
  static int Get_count()
  {
    return _count;
  }
  class B
  {
  public:
    B()
    {
            _count++;
      _a = 3;
    }
  private:
    int _a;
  };
private:
  int _A;
  static int _count;
};
int A::_count = 0;
int main()
{
  cout << sizeof(A) << endl;
  return 0;
}

我们可以看到计算A的大小时不包括B,可以这么理解,B是一个独立的类,只是受到A的访问限定符的限制,并且B天生就是A的友元,可以访问A的私有变量。

两个点:

  • A,B是独立的两个类,只是B受到A访问限定符的限制。
  • B天生就是A的友元。

其余不再多说。

lesson3-C++类和对象(下)(三)+https://developer.aliyun.com/article/1393918

目录
相关文章
|
15天前
|
存储 编译器 C语言
【C++语言2】类和对象(上)
【C++语言2】类和对象(上)
|
4天前
|
编译器 C++
【C++初阶】—— 类和对象 (下)
【C++初阶】—— 类和对象 (下)
7 2
|
4天前
|
存储 编译器 C++
【C++初阶】—— 类和对象 (中)
【C++初阶】—— 类和对象 (中)
10 3
|
4天前
|
存储 编译器 C语言
【C++初阶】—— 类和对象 (上)
【C++初阶】—— 类和对象 (上)
11 1
|
5天前
|
C++
【C++语言】类和对象(下)
【C++语言】类和对象(下)
|
5天前
|
编译器 C++ 存储
【C++语言】类和对象--默认成员函数 (中)
【C++语言】类和对象--默认成员函数 (中)
【C++语言】类和对象--默认成员函数 (中)
|
5天前
|
存储 C++ C语言
【C++语言】初步认识面向对象编程&&类和对象(上)
【C++语言】初步认识面向对象编程&&类和对象(上)
|
15天前
|
Java 编译器 C++
4. C++类和对象(下)
4. C++类和对象(下)
|
28天前
|
C语言 C++
从C语言到C++⑧(第二章_类和对象_下篇_续)笔试选择题和OJ题
从C语言到C++⑧(第二章_类和对象_下篇_续)笔试选择题和OJ题
21 0
|
28天前
|
Java 编译器 C语言
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象(下)
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象
12 0

热门文章

最新文章