类与对象的基础与对象特性【C++】

类与面向对象

**C++**面向对象的三大特性:封装继承多态

面向对象(Object-Oriented)是一种软件开发的方法论,它将程序中的数据和操作数据的逻辑封装在一起,以形成对象的概念,对象可以互相之间进行交互和通信。

博客源地址:修能的博客

名词解释

什么是类?

类(Class): 类是对象的抽象,它定义了一个对象的属性方法。类可以看作是创建对象的模板或蓝图

struct 和 class 之间的区别

struct 和 class 之间的区别 在许多编程语言中,包括C++和C#等,都支持使用structclass来定义数据结构和数据类型。下面是structclass之间的主要区别:

  1. 成员的默认访问权限: class是私有,struct公有。
  2. 继承能力: class支持继承,struct不支持继承。
  3. 分配方式: class是引用类型数据(堆区),struct是值类型数据(栈区)。
  4. 默认的拷贝方法:class是浅拷贝,struct逐成员拷贝。

什么是对象?

对象(Object)是****类的实例**,它是具体的实际存在的数据实体,具有类所定义的属性和方法。

什么是封装?

封装(Encapsulation): 封装是将数据操作数据的方法绑定在一起,通过限制对数据的访问,确保数据的完整性安全性

什么是继承?

继承(Inheritance): 继承允许一个类继承另一个类的特性和行为,从而实现代码的重用和扩展

什么是多态?

多态(Polymorphism): 多态允许使用统一的接口来操作不同类型的对象,提供了代码的灵活性和可维护性。

封装

在面向对象编程中,封装可以帮助保护数据和方法的访问权限,确保对数据的访问和操作符合预期并符合设计意图。

访问权限

权限的控制有三种:

  1. public 公共权限
    公开访问表示成员(属性或方法)对所有对象和其他类可见,并且可以被直接访问和调用。
  2. private 私有权限
    私有访问表示成员仅对所属类内部可见,其他类无法直接访问私有成员。私有成员只能被类内部的方法所使用。
  3. protected 保护权限
    保护访问类似于私有访问,但对于继承关系中的子类是可见的。即子类可以访问基类的保护成员,但其他类无法直接访问。但是仅仅也只是保护权限的内容。

私有权限

在将成员设置为私有时,一般会写一些公共方法来对私有成员进行读写的操作,即get()set()方法。

这样就可以对数据的读写性进行控制,只要不写私有成员getset方法就可以了。

这样还可以对数据的输入进行控制,只要在set()中添加判断逻辑,就可以控制数据的有效范围。

如何判断两个对象是否相等

有两种方法:

  1. 定义全局函数(不建议)
  2. 定义成员函数
bool student::isEqual(student stu)
{
    return stu.getName() == this->Name && stu.getGender() == this->Gender && stu.getAge() == this->Age;
}

对象的初始化和清理

构造函数

在实例化对象的时候自动的调用。

如果不写构造函数,对象会默认创建对象的默认的无参构造函数。

函数名与类名相同。

构造函数的分类

按参数分:

  1. 无参构造
  2. 有参构造

按调用的分类:

  1. 拷贝构造

    student(const student &stu);
    
    student s3(s1);
    

    const是因为不能改变原先对象的值

    &引用是因为防止递归调用

  2. 显式构造

    student s1 = student("xiunneg",student::GENDER::Male, 13);
    

    student("xiunneg",student::GENDER::Male, 13);是一个匿名对象

  3. 隐式构造(不建议,仅仅适用于单个参数的构造)

拷贝构造注意事项

当对象被以值的形式传递时会调用到拷贝构造函数。。

析构函数

用于对象的销毁前会自动调用来销毁对象。

函数名为:~类名()

深拷贝和浅拷贝

浅拷贝: 简单的赋值拷贝操作

深拷贝: 在堆区重新申请空间,进行拷贝操作

这两种拷贝的区别就是对于指针类型的数据的操作。

以下用A对象指源对象,B对象指通过拷贝构造A对象而得到的对象。

浅拷贝对于指针类型的复制只会复制指针的值,不会拷贝指针指向的值,就是说两个对象中的指针成员所指向的是同一个内存空间,通过A对象可以修改通过浅拷贝复制构造出的B对象的值。

深拷贝要求将指针的数据类型重新分配内存地址,再去赋值,这样就在修改B对象时不会修改A对象的数据了,因为指针指的不是同一块内存地址了。

inline Person::Person(const Person &other)
{
    data = new int;
    *data = *(other.data);
    cout << "深拷贝" << endl;
}

inline Person::Person(const Person &other)
{
    data = other.data;
    cout << "浅拷贝" << endl;
}

初始化列表

用于初始化属性的语法:

class Class{
private:
    int A;
    int B;
    int C;
public:
    Class(int a,int b,int c) : A(a),B(b),C(c) {};
}

对象成员

类的成员也可以是别的类的对象。

那么它们的构造函数和析构函数的调用顺序是怎样的呢?

遵循一个原则,谁在外部谁先构造,谁在内部谁先析构

静态成员

被关键词static修饰过变量或者函数被称为静态成员,它们有以下特点:

  1. 静态成员属性:它是属于类本身的属性,而不是属于实例化对象的属性,也就是说所有的实例化对象共有这个成员,所有的对象实例的这个值是一样的。
  2. 静态成员函数:它无法访问非静态成员属性,也无法使用this指针。静态成员函数可以通过类名来直接调用,不需要通过类的实例。
  3. 静态成员的访问控制:静态成员遵循类的访问控制规则。私有的静态成员只能被类内的函数访问,公有的静态成员可以被任何使用类的代码访问。

静态成员一般不会通过实例来访问,都是使用类名来进行访问:classname::static member

C++对象模型

成员变量和成员函数分开存储

空对象的占用内存空间是1,是因为编译器会将空对象分配一个字节空间,为了区分对象占内存的位置。

对象的内存空间中只会存储对象中的非静态的成员属性和虚函数表,函数成员存储在类的代码段中。

静态成员属性在类内部声明,在类的代码段中进行定义和初始化,并且存储在全局数据区(Global Data Segment)

this指针

this指针的本质是classname* const this,是一个指针常量。

一个非静态成员函数只会生成一份函数实例,也就是多个同类型的对象会去调用同一个函数实例,那如果区分调用的对象就成了一个问题。

this指针可以解决这个问题。

this指针是C++ 提供的特殊对象指针,this指针指向被调用的成员函数所属的对象。

用处如下:

  • 当函数的参数与类的属性同名时,需要通过this来区分。
  • 在类的非静态成员函数返回对象本身时,可使用return *this,同时函数的返回类型也要写成类对象的引用类型Person& func(Person p1) {return *this},否则返回的是一个新的值,利用是函数可以链式调用。

const修饰的成员函数

  • 常函数

    成员函数后加const后我们称这个函数为常函数。其本质是修饰了this指针。

    void Testfunc() const {};
    
    classname* const this ----> const classname* const this
    

    被设置为常函数后,函数的内部不能修改成员属性,也就是设置了该函数为只读

    如果想要在常函数中修改属性,只要在想要修改的对象前用mutable修饰即可。

  • 常对象

    声明对象前加const称该对象为常对象

    常对象只能调用常函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值