C++类与对象总结

上//

  1. this对象
  1. 实参和形参都不能写,函数内部可以调用this
  2. This一般存在函数栈帧中,少部分用寄存器
  3. const Data*p  这里指针所指的对象固定,即对象不可修改
  4. Data* const p  这里指针的指向固定
  1. c和c++的stack对比
  1. c是散装,c++是封装
  2. c需要typedef,c++可以直接用类名
  3. c++有缺省参数,较方便(如开空间默认n=4)
  4. c++不用传地址,编译器帮你传this
  5. c可以随便读数据,如a.[top-1],c++不能访问private
  1. 面向对象的三大特征
  1. 封装
  2. 继承
  3. 多态
  1. 运算符重载
  1. 是一种拥有特殊名字的函数
  2. 名字由operator和运算符构成

实例:bool oprator==(Date d1,Date d2)

  1. operator==(d1,d2)等价于d1==d2
  2. 如果重载运算符函数是成员函数,则二元函数只用传一个参数,第一个运算对象由this隐式给出
  3. 有5个运算符不能重载:.*   ::    sizeof   ?:    .
  4. 重载运算符至少有一个类类型的参数
  5. 全局函数和对象函数同时存在时,运算符重载优先调用对象函数;
  1. 赋值运算符重载

   完成两个已经存在的对象之间的拷贝

   拷贝构造

   一个存在的对象拷贝初始化给另一个要创建的对象

(1)参数类型:const T&,传递引用可以提高传参效率

(2)返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值

(3)检测是否自己给自己赋值

(4)返回*this :要符合连续赋值的含义

Date& operato

(5)前置++和后置++重载

Date& operator++()

{

_day += 1;

return *this;

}

++d1

Date operator++(int)

{

Date temp(*this);

_day += 1;

return temp;

}

d1++

6.函数指针类型(若是成员函数,则在pf前加A::)

(1)void func()

(2)Typedef void(*PF)();Typedef void(A::*PF)()

void(*pf)()=nullptr;等价于PF pf=nullptr;

void(A::*pf)()=nullptr  

(3)普通函数函数名即为函数指针,成员函数要加&才是函数指针;

(4)普通函数回调(*pf)(),成员函数回调(st1.*pf)()

中//六个默认成员函数

  1. 构造函数

不是开空间,而是初始化(局部变量的空间在创造栈帧时就已经开好)

  1. 特点:函数名和类名相同
  2. 无返回值也无void
  3. 实例化时系统会自动调用
  4. 可以重载

     重载时该怎么调用?(以date类为例)

class Date

{

public:

Date()

    {

        _year = 2024;

        _month = 07;

        _day = 17;

    }

    Date(int year = 1900, int month = 1, int day = 1)

    {

        _year = year;

        _month = month;

        _day = day;

    }

private:

    int _year;

    int _month;

    int _day;

};

          无参:Date d1;

有参  Date d1(2025, 4, 25);

Ps;这里的Date是类而不是函数名,d1是对象;即在声明对象时自动初始化;

Ps:最好用全缺省,此时不能用无参,否则会有函数歧义

  1. 不写时,编译器会自动生成一个无参的构造函数
  2. 无参构造函数全缺省构造函数编译器自动生成的构造函数都叫默认构造函数

即不传参的都叫默认构造,三者有且只有一个存在

  1. 编译器生成的构造函数,大多数没有初始化的功能,少部分对内置类型的变量会处理。

特例:class MyQueue

{

private:

    Stack _pushst;

    Stack _popst;

};

若stack构造函数已经写好,编译器生成的queue的构造函数会自动调用,初始化两个栈

即对于自定义类型的成员变量,要求调用这个成员变量的默认构造函数初始化。

  1. 析构函数
  1. 析构函数名是在类名前加上字符~
  2. 无参也无返回值
  3. 一个类只有一个析构函数
  4. 对象生命周期结束时,系统会自动调用析构函数
  5. 不写时,编译器自动生成的析构函数不会对内置类型处理,自定义类型成员会调用它的析构函数
  6. 后定义的先析构;

~Stack()

{

if (_array) {

free(_array);

_array = NULL;

_capacity = 0;

_size = 0;

}

}

  1. 拷贝构造构造

   如果一个构造函数的以第一个参数是自身类型的引用,且任何额外参数都有默认值,则此构造函数叫做拷贝构造函数

(1) 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错, 因为会引发无穷递归调用.

  1. 若未显式定义,编译器会生成默认的拷 贝构造函数。默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
  2. 浅拷贝直接复制地址,共享一块内存,深拷贝则是拷贝资源,互不干扰。
  3. 需要实现析构的类,也需要实现显示的拷贝构造,即深拷贝
  4. 两种方式调用拷贝构造:Stack st1(st2)或者Stack st1=st2

 Date(const Date& d)   //

{

_year = d._year;

_month = d._month;

_day = d._day;

}

下//进阶

  1. 再识构造函数

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟 一个放在括号中的初始值或表达式。

class Date

{

public:

Date(int year, int month, int day)

: _year(year)

    , _month(month)

    , _day(day)

 };

【注意】

(1)每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

(2) 类中包含以下成员,必须放在初始化列表位置进行初始化:

引用成员变量/ /const成员变量// 自定义类型成员(且该类没有默认构造函数时) 

  1. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量, 一定会先使用初始化列表初始化。

   

  1. Const

2.1 概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用

static修饰成员函数,称之为静态成员函数静态成员变量一定要在类外进行初始化

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

Class A{

public:

A() { ++_scount; }

A(const A& t) { ++_scount; }

~A() { --_scount; }

static int GetACount() { return _scount; }

private:

static int _scount;

};

int A::_scount = 0;

void TestA()

{

cout << A::GetACount() << endl;

A a1, a2;

A a3(a1);

cout << A::GetACount() << endl;

}

1. 静态成员所有类对象所共享,不属于某个具体的对象,存放在静态区

2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明 

3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问

4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员

5. 静态成员也是类的成员,受publicprotectedprivate 访问限定符的限制

  1. 友元

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

友元不宜多用。

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

  1. 友元函数

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

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

  1. 友元类

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

友元关系是单向的,不具有交换性。

比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接

访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。

友元关系不能传递

如果CB的友元, BA的友元,则不能说明CA的友元。

友元关系不能继承,在继承位置再给大家详细介绍。

4.内部类

概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,

它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越

的访问权限。

注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访

问外部类中的所有成员。但是外部类不是内部类的友元。

特性:

1. 内部类可以定义在外部类的publicprotectedprivate都是可以的。

2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。

3. sizeof(外部类)=外部类,和内部类没有任何关系。 

5.匿名对象

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值