【面向对象程序设计与C++】学习笔记

北京交通大学《面向对象程序设计与C++》课程学习笔记

目录

一、认识面向对象

1.什么是面向对象

2.类与对象

对象的定义

类的定义

 类与对象的关系

3.面向对象的基本特征

抽象性

封装性

继承性

多态性

二、C++类

1.C++类的定义与实现

C++类的定义

C++类的实现

2.构造函数与析构函数

 成员变量初始化

构造函数的定义

析构函数的定义

拷贝构造函数

this指针

三、静态成员

1.静态数据成员

关于类的属性

初始化时机

2.静态成员函数

四、组合类

1.组合类基本原理

2.组合类的优点

代码复用

模块化设计

易于理解和调试

五、友元

1.友元类

2.友元函数

3.友元的优缺点

优点

缺点

六、常对象和常对象成员

1.常对象

定义与声明

特点与限制

 2.常对象成员

常数据成员

常成员函数

 七、继承与多态

1.继承与派生

派生

派生类的实现

继承方式

派生类的构造函数和析构函数

2.多继承

多继承派生类定义形式

多继承派生类构造函数

3.虚基类

虚基类的定义

虚基类构造函数的调用

3.多态

编译时多态(静态多态)

运行时多态(动态多态)

 4.虚函数

虚函数的声明

虚函数的作用 

注意事项

 纯虚函数与抽象类

 八、重载

1.函数重载

基本概念

实现原理

注意事项

2.运算符重载

 一般形式

运算符函数原型

九、模板

1.模板的定义

 2.函数模板

定义

使用

函数模板的重载

3.类模板

定义

 使用

4.模板的特化

函数模板特化

 类模板特化

十、写在最后


一、认识面向对象

1.什么是面向对象

面向对象(Object Oriented)是一种软件开发方法,一种编程范式。面向对象的概念和应用已超越了程序设计与软件开发,扩展到如应用结构、应用平台等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。

简而言之,面向过程就是根据业务从上到下写代码,而面向对象就是将数据和函数绑定到一起,加速开发程序,减少重复的代码的重写过程。

2.类与对象

面向对象程序设计应用以对象作为基本元素的方法,用计算机语言描述并处理一个问题

对象的定义
  • 对象可以是人们要研究的任何事物,包括具体的(如程序、计算机)和抽象的(如思想、规则、计划等)
  • 每一类对象都有属性(如大小、形状、重量等)和行为(如行走、转弯等)
类的定义
  • 同类对象公共的属性和行为
 类与对象的关系
  • 类是具有相同数据结构(属性)和相同操作功能(行为)的对象的集合,它规定了这些对象的公共属性和行为方法     
  • 对象是类的一个实例,例如,汽车是一个类,而行驶在公路上的一辆汽车则是一个对象

例如:

class CStudent {

private: //学生的属性
    char mNo[9];         // 学号,9位字符数组
    char* mpName;        // 姓名指针
    int mScore[5];       // 五门功课成绩
    static int mCount;   // 静态成员变量,用于计数学生对象数量

public:  //学生的行为(方法)
    void SetStudent(const char* name, int scores[5]);   // 设置学生信息
    void ShowStudent() const;                           // 显示学生信息
};

3.面向对象的基本特征

抽象性
  • 抽象是指对一类对象进行概括,抽出他们共同的性质并加以描述的过程
封装性
  • 封装是将抽象得到的属性数据和行为代码结合,同时,封装避免了外部与对象之间的影响(对象无法影响外部数据,外部对对象的修改只能通过public方法)
class CStudent {

private: //学生的属性
    char mNo[9];         // 学号,9位字符数组
    char* mpName;        // 姓名指针
    int mScore[5];       // 五门功课成绩
    static int mCount;   // 静态成员变量,用于计数学生对象数量

public:  //学生的行为(方法)
    void SetStudent(const char* name, int scores[5]);   // 设置学生信息
    void ShowStudent() const;                           // 显示学生信息
};

在上述代码中,private中的数据外部无法访问,但是可通过public中的函数(外部接口)来达到访问的目的

继承性
  • 继承是指一个新类可以从现有的类派生而来,很好地解决了软件的可重用性问题
多态性
  • 多态是指类中具有相似功能的不同函数使用同一个名称来实现,并且允许不同类的对象对同一消息做出不同的响应

二、C++类

1.C++类的定义与实现

C++类的定义
  • C++将对象的属性抽象为数据成员,将对象的行为抽象为成员函数。数据成员又称成员变量,成员函数又称方法
C++类的实现
class < 类名 > {
private:
    < 私有数据成员与私有成员函数的声明列表 >;
public:
    < 公有数据成员与公有成员函数的声明列表 >;
protected:
    < 保护数据成员与保护成员函数的声明列表 >;
}; 

例如:

//CStudent.h
class CStudent {

private:
    char mNo[9];         // 学号,9位字符数组
    char* mpName;        // 姓名指针
    int mScore[5];       // 五门功课成绩
    static int mCount;   // 静态成员变量,用于计数学生对象数量

public:
    CStudent();                              // 默认构造函数
    CStudent(const CStudent& zS);            // 拷贝构造函数
};

2.构造函数与析构函数

 成员变量初始化
  • 在定义类时不能对成员变量进行初始化,因为无法确定成员变量属于哪一个对象。成员变量一般都定义为私有属性,也不能在声明对象后利用赋值运算对成员变量进行初始化。成员变量的初始化一般是利用一个名为构造函数的成员函数来完成
构造函数的定义
  • 构造函数是一种特殊的成员函数,它是在创建对象时(声明或用new动态创建)系统自动调用的成员函数
析构函数的定义
  • 析构函数也是一种特殊的成员函数,它是在对象生存期结束时系统自动调用的成员函数

构造函数名称与类名相同,析构函数名称必须在类名前加上" ~ "符号 

例如:

//构造函数
CStudent::CStudent()
{
	mCount++; //每次创建学生 计数加一

	sprintf(mNo,"1728%04d",mCount);   //按照计数设置学号
	mpName = NULL;                    //姓名指针置空
	memset(mScore,0,sizeof(mScore));  //清空成绩数组

}

//析构函数
CStudent::~CStudent()
{
    delete[] mpName;
}

析构函数在运行时遵循“先进后出,后进先出”的原则 (类比数据结构中的栈)

拷贝构造函数
  • 拷贝构造函数的参数是本类对象的一个引用
  • 若未定义拷贝构造函数,编译系统自动为类添加一个默认的拷贝构造函数
  • 默认拷贝构造函数采取浅拷贝

浅拷贝:

  • 只进行基本数据类型的拷贝
  • 当数据成员为指针类型时,存在潜在危险,即两个对象的指针指向同一内存区域

例如:

//构造函数
//CStudent::CStudent() { ... }

//拷贝构造函数
CStudent::CStudent(const CStudent& zS) 
{
    strcpy(mNo, zS.mNo);        // 复制学号
    mpName = new char[strlen(zS.mpName) + 1];
    strcpy(mpName, zS.mpName);  // 深拷贝姓名

    for (int i = 0; i < 5; i++) 
    {
        mScore[i] = zS.mScore[i];  // 复制成绩数组
    }
}

//析构函数
//CStudent::~CStudent() { ... }
this指针
  • this指针是一个指向当前对象的特殊指针

  • 每个非静态成员函数隐藏有一个this指针的函数参数,当通过一个对象调用函数时,编译器将把当前对象的地址传递给this指针

例如:

//用户输入的代码
void CTime::showTime {
    cout << hour << minute << second << endl;
}

//编译器处理的代码
void CTime::showTime(CTime* const this) {
    cout << this->hour << this->minute << this->second << endl;
}

CTime t1(11, 30);
t1.showTime();   //用户输入的代码
t1.showTime(&t1) //编译器处理的代码

三、静态成员

1.静态数据成员

关于类的属性
  • 不同对象具有不同的属性值
  • 所有对象具有相同的属性值
  • 类属性的声明:
static < 数据类型 >< 静态成员名 >
初始化时机
  • 实例属性:对象创建时,构造函数
  • 类属性:所有类共享,类外部初始化
< 数据类型 >< 类名 >::< 静态数据成员名 > = < 初始值 >

例如:

class Railway {
public:
    Railway(const std::string& name, int length) : railwayName(name), railwayLength(length) {
        // 每创建一个对象,铁路总长度累加
        totalLength += length;  
    }
    void displayInfo() const {
        std::cout << "铁路名称: " << railwayName << ", 长度: " << railwayLength << " 公里" << std::endl;
    }
    static int getTotalLength() {
        return totalLength;  
    }
private:
    std::string railwayName;
    int railwayLength;

    // 静态数据成员,用于记录所有铁路的总长度
    static int totalLength;  
};

// 初始化静态数据成员
int Railway::totalLength = 0; 

2.静态成员函数

  • 静态成员函数也与一个类相关联,而不是只与一个特定的对象相关联

  • 静态成员函数只能访问类的静态成员(成员变量与成员函数),而不能访问类的非静态成员

  • 静态成员函数访问非静态成员的方法:将对象作为静态成员函数的参数 (不建议)

  • 既要访问静态成员,又要访问非静态成员,建议使用普通成员函数

  • 区别于非静态成员函数,静态成员函数没有 this 指针,因为类的静态成员函数只有一个运行实例

例如:

class Train {
public:
    // 构造函数,用于初始化列车信息
    Train(const std::string& name, int speed, int capacity)
        : trainName(name), trainSpeed(speed), passengerCapacity(capacity) {
        // 每创建一辆列车,将其信息添加到静态成员变量 allTrains 中
        allTrains.push_back(this);  
    }

    // 静态成员函数,用于显示所有列车的信息
    static void displayAllTrains() {
        std::cout << "所有列车信息如下:" << std::endl;
        for (const auto& train : allTrains) {
            train->displayTrainInfo();  
        }
    }

    // 普通成员函数,用于显示当前列车的信息
    void displayTrainInfo() const {
        std::cout << "列车名称:" << trainName << ",速度:" << trainSpeed << " km/h,载客量:" << passengerCapacity << " 人" << std::endl;
    }

private:
    std::string trainName;
    int trainSpeed;
    int passengerCapacity;

    // 静态数据成员,用于存储所有列车的指针
    static std::vector<Train*> allTrains;  
};

// 初始化静态数据成员
std::vector<Train*> Train::allTrains;  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值