C++学习-类2

静态成员

静态数据成员

关键字static,可以实现不同对象之间的数据共享。
组成:类内声明类外初始化。两者缺一不可

\\类内声明 
static 数据类型 名;  
\\类外初始化
数据类型 类名::静态数据成员名=初始值;
  1. 必须要类内声明内外初始化,如果内外无初始化会报错。
    定义类时不会为静态数据成员分配空间,类外初始化才分配空间
  2. 和其他类内的数据成员一样,private只能在类内使用,public可以在内外使用
  3. 不属于对象属于类,但所有对象都共用。可以通过域操作符直接调用 如类名::rate,也可以有可以通过对象引用,如:对象名.rate
  4. 程序开始时产生,结束时消失

补充:静态常量成员,定义:static const 类型 数据成员名
静态常量成员后两种初始化方法,一种是类外,一种是类内。

class AA
{
    private:
        static const int num;
};
const int AA::num=3;
//或者
class AA
{
    private:
        static const int num=3;
};

而静态数据成员必须是类内声明,类外初始化。

静态成员函数

静态成员函数时为累的全体对象服务,不需要借助任何对象就可以调用,无法处理类中非静态成员变量,也不允许需用this指针。
类内定义在定义前在static,类内声明类外定义,只要在声明前加static,类外定义时不需要加static
调用方式:类名::函数名 或 对象.函数名

  • 静态成员函数不能访问一帮的数据成员,而只能访问静态数据成员或其它静态成员函数。但如果传递该类的对象或对象的引用,或者在函数内创造一个该类的对象,那么可以使用该对象的所有成员,包括私有(如果不是常对象)。
#include<iostream>
using namespace std;

class AA
{
    private:
        int a;
    public:
    AA(int h=0)
    {
        a=h;
    }
    static void abc(AA &aa)
    {
        aa.a++;
        cout<<aa.a;
    }
};

int main()
{
    AA aa;
    AA::abc(aa);
    return 0;
}

结果输出1。

友元

友元不是类的成员,当他可以访问类的任何成员包括私有成员,友元包括友元函数,友元成员函数,友元类。
friend是关键字,格式为:

friend 返回类型 函数名(形参表)
{
    函数体;
}

下面依次介绍三种。
友元函数

//在类A中加入
friend void f();//把函数f作为类A的友元,可以类内定义也可以类外定义函数。如果类外定义,类外不需friend。

友元成员函数函数:

B的成员函数:int func(double);
若声明为类A的友元,在类A定义中加入:
friend int B::func(double);

友元类

//在类A中加入
friend class B;//把整个类B作为类A的友元

友元关系声明可以放在函数任意一个地方,,可以私有也可以公有,效果不会影响,不过一般放在最前面或最后面。
补充:前向引用声明,和函数的声明差不多,可以在后面定义类然后在开头加上声明。

#include <iostream>
using namespace std;
class B; //前向引用声明。
class A{
    public:
        void f(B &b);
    private:
        B *b; // 不能使用 B b
};
class B{
    public:
        void g(A a);
    private:
        A a;
};

但前向引用声明不是万能的。
在声明之前,不能声明该类的对象,也不能在内联成员函数中使用该类对象。
前向引用声明时,只能使用被声明的符号,不能涉及类的任何细节。

class Fred;
class Braney{
  Fred x; // 错误:类Fred的声明尚不完善。
};
class Fred{
  Braney y;
};

课堂上的笔记补充:

  • 如果自己定义任意一个普通的构造函数,则系统不再提供默认构造函数,但会提供一个默认的拷贝构造函数;如果定义了一个拷贝构造函数,则系统不再提供默认构造函数和默认拷贝构造函数
  • 如果函数的返回值是常量,或传递的实参是个常量,或给对象初始化的是一个常量,如Clock(1,2,3);(Clock是类名),则调用构造函数而不是拷贝构造函数。
posted @ 2020-12-24 13:13  七铭的魔法师  阅读(50)  评论(0编辑  收藏  举报