当前位置: 首页 > news >正文

2026《数据结构》考研复习笔记二(C++面向对象)

C++面向对象

  • 一、类
  • 二、继承
  • 三、重载运算符和重载函数
  • 四、多态
  • 代码示例

一、类

1.1类&对象

class classname//class是关键词,classname是类名
{
Access specifiers://访问修饰符:private/public/protected
Date members/variables;//变量
Member functions(){}//方法
}//分号结束一个类

【例】定义Box类

class Box//盒子 private: 
double length;//长 
double breadth;//宽 
double height;//高 //成员函数声明   
public:  
tuple< double,double,double>GetMessage();//获取盒子信息 
void set(double len,double bre,double hei);//修改盒子信息 
} 
}; tuple< double,double,double> Box::GetMessage(){
return {length,breadth,height}; 
} void Box::set(double len,double bre,double hei){ 
length=len; 
breadth=bre;  
height=hei; 
} 访问类的成员函数: 
Box Box1; 
Box1.GetMessage();//此处有省略,应当有构造函数,下面介绍

1.2类成员函数

成员函数的作用:
类的成员函数只属于该类,是类的一个成员,它可以访问类的成员,对具体的对象进行操作(private修饰的成员变量只能由成员函数进行修改)

成员函数的定义:
成员函数可以定义在类定义内部,或单独使用范围解析运算符::定义
如:

tuple< double,double,double> Box::GetMessage(){
return {length,breadth,height};

1.3类访问修饰符

public成员:在类的外部可以访问,不需要通过成员函数设置和获取共有变量的值

private成员:在类的外部不可访问,只有该类和友元函数可以访问私有成员

protected成员:与private成员相似,但是protected成员可以在派生类(子类)中访问

三种继承方式:
public继承:基类public成员、protected成员、private成员的访问属性在派生类中分别变成了public,protected,private
protected继承:基类public成员、protected成员、private成员的访问属性在派生类中分别变成了protected,protected,private
private继承:基类public成员、protected成员、private成员的访问属性在派生类中分别变成了private,private,private

1.4构造函数&析构函数

#include< iostream> 
using namespace std; class Line 
{ 
public: 
void setLength(double len); 
double getLength(void); 
Line();//不带参数的构造函数 
Line(double len);//带参数的构造函数 
~Line();//析构函数 private: 
double length; 
}; Line::Line(void){ 
cout<<"Object is being create"<< endl; 
} Line::Line(double len){ 
cout<<"Object is being create,length= "<< len<< endl; 
} Line::~Line(void){ 
cout<<"Object is being deleted"<< endl; 
} void Line::setLength(double len){ 
length=len; 
} double Line::getLength(void){ 
return length; 
} int main(){ 
Line line; 
line.setLength(6.0); 
cout<<"Length of line : "<< line.getLength()<< endl; 
return 0; 
} //编译上述代码并执行产生下面结果: 
//Object is being created 
//Length of line : 6 
//Object is being deleted

1.5拷贝构造函数
拷贝构造函数属于构造函数,如果类带有指针变量并有动态内存分配,它在创建对象时,使用同一类中之前创建的对象来初始化新创建的对象。通常用于:

  • 同一个同类型的对象初始化新对象(=赋值)
  • 复制对象把它作为参数传递给函数
  • 复制对象,并从函数返回这个对象

常见形式:
classname (const classname &obj){……}//obj是一个对象的引用,用于初始化另一个对象

【例】拷贝构造函数——此处省略class的其他函数,只展示拷贝构造函数的定义以及用法

Line::Line(const Line &obj)
{cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;ptr = new int;*ptr = *obj.ptr; // 拷贝值
}
// 程序的主函数
int main( )
{Line line(10);Line line2=line1;print(line);return 0;
}

1.6友元函数
类的友元函数在类的定义中声明,但不是成员函数。友元函数定义在类外部,有权访问类的所有private成员和protected成员。

友元可以是函数(友元函数),也可以是类(友元类)
如:
friend void printWidth(Box box);
friend class ClassTwo;

【例】友元函数

class Box
{double width;
public:friend void printWidth( Box box );void setWidth( double wid );
};
// 请注意:printWidth() 不是任何类的成员函数
void printWidth( Box box )
{/* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */cout << "Width of box : " << box.width <<endl;
}
printWidth( box );

1.7内联函数
函数名前有关键字inline的函数为内联函数,内联函数在编译时,编辑器会把该函数的代码副本放置在每个调用该函数的地方。类定义中定义的函数都是内联函数

1.8this指针
this是一个隐藏的指针,可以在类的成员函数中使用,用来指向当前调用对象(当一个对象的成员函数被调用时,编辑器会隐式地传递该对象的地址作为this指针)。友元函数没有this指针,因为友元不是类的成员,只有成员函数才有this指针

例如:

int compare(Box box){return this->Volume() > box.Volume();}Box1.compare(Box2);

1.9指向类的指针
一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算符 ->

常见操作:

1. MyClass obj;MyClass *ptr=&obj;//指向对象
2. MyClass *ptr=new MyClass;//动态分配
3. void processObject(MyClass *ptr){ptr->display():}//作为函数参数传递

1.10类的静态对象
使用static关键字把类成员定义为静态时,无论创建多少个类的对象,静态成员变量只有一个副本(静态成员在类的所有对象中是共享的)。不能把静态成员变量的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符::重新声明静态变量从而对它进行初始化

静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问。

静态成员函数没有this指针,只能访问静态成员(包含静态成员变量和静态成员函数)。静态函数即使在类对象不存在的情况下也能被调用,只要使用classname::即可访问

练习实例——点击跳转(笔者本人应用知识点写的代码)

二、继承

2.1派生类
基本形式:class derived_class:access_specifier base_class。其中derived_class是派生类名,access_specifier 是public\protected\private中的一个,base_class是基类名。例如:class Dog:public Animal{};

// 基类 
class Shape  { protected: int width; int height; 
}; // 派生类 
class Rectangle: public Shape { public: int getArea() {  return (width * height);  } 
}; 

派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。

2.2多继承
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…{
<派生类类体>
};

class A: public B, public C{……}

三、重载运算符和重载函数

C++允许在同一个作用域中函数和运算符有多个定义(参数列表不同)——函数重载运算符重载

3.1函数重载
重载的同名函数形参必须不同(参数的个数、类型或者顺序)。如:

void print(int i) {cout << "整数为: " << i << endl;}
void print(double  f) {cout << "浮点数为: " << f << endl;}
void print(char c[]) {cout << "字符串为: " << c << endl;}

3.2运算符重载
基本形式:< return > operator < op>(parameter)

点击运算符可查看重载代码

一元运算符 递增运算符++,递减运算符--,负号-,逻辑非!
二元运算符 加+,减-,乘*,除/
关系运算符 < , > , <= , >= , ==
输入/输出运算符 << , >>
赋值运算符 =
函数调用运算符 ()
下标运算符 []
类成员访问运算符 ->

四、多态

4.1虚函数

  • 在基类声明一个虚函数(关键字为virtual)
  • 派生类可以重写虚函数
  • 调用虚函数时,会根据对象的实际类型决定调用哪个版本的函数
class Animal {
public:virtual void sound() {  // 虚函数cout << "Animal makes a sound" << endl;}
};class Dog : public Animal {
public:void sound() override {  // 重写虚函数cout << "Dog barks" << endl;}
};

4.2动态绑定

  • 在运行时决定函数调用的具体实现
  • 需要使用指向基类的指针或引用来调用虚函数,运行时根据对象的类型决定调用哪个函数
Animal *animal = new Dog();animal->sound();  // 输出: Dog barks

4.3纯虚函数
当想要在基类中定义虚函数,但又不能对虚函数给出有意义的实现,这是会用到纯虚函数

  • 一个包含纯虚函数的类被称为抽象类,不能被直接实例化
  • 纯虚函数没有函数体 ,声明时使用=0
  • 强制派生类提供具体的实现
class Shape {
public:virtual int area() = 0;  // 纯虚函数,强制子类实现此方法
};class Rectangle : public Shape {
private:int width, height;
public:Rectangle(int w, int h) : width(w), height(h) { }int area() override {  // 实现纯虚函数return width * height;}
};

4.4多态的实现机制

  • 虚函数表:C++运行时使用虚函数表来实现多态,每个包含虚函数的类都有一个虚函数表,表中存储了指向类中所有虚函数的指针

本节实例处

代码示例


”类“练习代码

#include<iostream>
#include<tuple>
using namespace std;class Box {
private:int hei;int len;int bre;Box* next;static int num;
public:Box();//不带参数的构造函数Box(int hei, int len, int bre, Box* next = NULL);//带参数的构造函数Box(const Box& box);//拷贝构造函数(浅拷贝&深拷贝)~Box();//析构函数void set(int hei, int len, int bre, Box* next = NULL);tuple<int, int, int, Box*>GetMessage();int Volume();friend void print(const Box& box);
};int Box::num = 0;//初始化静态变量int main() {Box box(1, 1, 1);cout << "box的体积为" << box.Volume() << endl;print(box);return 0;
}Box::Box():hei(0),len(0),bre(0),next(NULL) {num++;cout << "Block box is being created" << endl;
}Box::Box(int hei, int len, int bre, Box* next) :hei(hei), len(len), bre(bre), next(next) {num++;cout << "A box is being created, whose hei is " << hei << " ,len is " << len << " and bre is " << bre << endl;
}Box::Box(const Box& box) {num++;hei = box.hei;len = box.len;bre = box.bre;next = new Box;*next = *box.next;cout << "A box is being created, whose hei is " << hei << " ,len is " << len << " and bre is " << bre << endl;
}Box::~Box() {cout << "A box is being deleted, whose hei is " << hei << " ,len is " << len << " and bre is " << bre << endl;
}void Box::set(int hei, int len, int bre, Box* next) {this->hei = hei;this->len = len;this->bre = bre;this->next = next;
}tuple<int, int, int, Box*> Box::GetMessage() {return { hei,len,bre ,next };
}int Box::Volume() {return hei * len * bre;
}void print(const Box& box) {cout << "This box message is :" << "height(" << box.hei << ")" << " " << "length(" << box.len << ")" << " " << "breadth(" << box.bre << ")" << endl;
}

跳转返回——继承

成员函数:ReturnType operator-() const{……}
全局函数:ReturnType operator-(const ClassType&obj){……}


递增运算符++
前置递增++obj重载(成员函数)

class Counter {
private:int count;
public:Counter(int c = 0) : count(c) {}// 前置递增 ++objCounter& operator++() {++count;       // 先递增return *this;  // 返回当前对象的引用}int getCount() const { return count; }
};int main() {Counter c(5);++c;  // 调用 operator++()std::cout << c.getCount();  // 输出 6
}

前置递增++obj重载(全局函数)

class Counter {
private:int count;
public:Counter(int c = 0) : count(c) {}friend Counter& operator++(Counter& c);  // 声明友元int getCount() const { return count; }
};// 全局前置 ++
Counter& operator++(Counter& c) {++c.count;return c;
}

后置递增obj++重载(成员函数)

class Counter {
private:int count;
public:Counter(int c = 0) : count(c) {}// 后置递增 obj++Counter operator++(int) {//int是占位参数,用于区分前置和后置Counter temp = *this;  // 保存当前值++count;               // 递增return temp;           // 返回旧值}int getCount() const { return count; }
};int main() {Counter c(5);Counter old = c++;  // 调用 operator++(int)std::cout << old.getCount();  // 输出 5(旧值)std::cout << c.getCount();    // 输出 6(新值)
}

后置递增obj++重载(全局函数)

class Counter {
private:int count;
public:Counter(int c = 0) : count(c) {}friend Counter operator++(Counter& c, int);  // 声明友元int getCount() const { return count; }
};// 全局后置 ++
Counter operator++(Counter& c, int) {Counter temp = c;++c.count;return temp;
}

跳转返回——多态

负号-
成员函数重载:

   class Number {
private:int value;
public:Number(int v) : value(v) {}// 一元减运算符重载(成员函数)Number operator-() const {return Number(-value);}int getValue() const { return value; }
};int main() {Number n(5);Number neg = -n;  // 调用重载的一元减运算符std::cout << neg.getValue();  // 输出 -5
}

全局函数重载:

class Number {
private:int value;
public:Number(int v) : value(v) {}int getValue() const { return value; }
};// 一元减运算符重载(非成员函数)
Number operator-(const Number& num) {return Number(-num.getValue());
}int main() {Number n(10);Number neg = -n;  // 调用重载的一元减运算符std::cout << neg.getValue();  // 输出 -10
}

跳转返回——多态

加+
成员函数重载

class Box {
private:int hei, len, bre;
public:// ...(其他成员函数和构造函数)// 成员函数重载 +Box operator+(const Box& other) const {return Box(hei + other.hei,  // 高度相加len + other.len,  // 长度相加bre + other.bre   // 宽度相加);}
};

全局函数重载

class Box {
private:int hei, len, bre;
public:// ...(构造函数和其他成员函数)// 声明友元,让全局函数能访问私有成员friend Box operator+(const Box& lhs, const Box& rhs);
};// 全局函数重载 +
Box operator+(const Box& lhs, const Box& rhs) {return Box(lhs.hei + rhs.hei,lhs.len + rhs.len,lhs.bre + rhs.bre);
}

跳转返回——多态

等于==
成员函数

class Box {
private:int hei, len, bre;
public:// ...(其他成员函数和构造函数)// 成员函数重载 ==bool operator==(const Box& other) const {return (hei == other.hei) && (len == other.len) && (bre == other.bre);}
};

全局函数

class Box {
private:int hei, len, bre;
public:// ...(构造函数和其他成员函数)// 声明友元,让全局函数能访问私有成员friend bool operator==(const Box& lhs, const Box& rhs);
};// 全局函数重载 ==
bool operator==(const Box& lhs, const Box& rhs) {return (lhs.hei == rhs.hei) && (lhs.len == rhs.len) && (lhs.bre == rhs.bre);
}

跳转返回——多态

输入>>
全局函数

#include <iostream>
using namespace std;class Box {
private:int hei, len, bre;
public:// 声明友元函数,允许访问私有成员friend istream& operator>>(istream& is, Box& box);
};// 全局函数重载 >>
istream& operator>>(istream& is, Box& box) {is >> box.hei >> box.len >> box.bre;  // 按顺序读取长、宽、高return is;  // 返回输入流以支持链式调用(如 cin >> box1 >> box2)
}

跳转返回——多态

赋值=

class Box {
private:int hei, len, bre;Box* next;  // 假设包含动态分配的资源
public:// ...(其他成员函数和构造函数)// 重载赋值运算符 =Box& operator=(const Box& other) {if (this != &other) {  // 防止自赋值(如 a = a)hei = other.hei;len = other.len;bre = other.bre;// 深拷贝 next(如果存在)if (next != nullptr) {delete next;  // 释放原有资源next = nullptr;}if (other.next != nullptr) {next = new Box(*other.next);  // 深拷贝}}return *this;  // 返回当前对象的引用}
};

跳转返回——多态

函数调用运算符()

#include <iostream>
using namespace std;class Adder {int value;
public:Adder(int v) : value(v) {}// 重载函数调用运算符int operator()(int x) {return value + x;}
};int main() {Adder add5(5);  // 创建一个Adder对象,初始值为5cout << add5(10) << endl;  // 像函数一样调用,输出15cout << add5(20) << endl;  // 输出25return 0;
}

跳转返回——多态

下标运算符[]

#include <iostream>
#include <vector>
using namespace std;class IntArray {vector<int> data;
public:IntArray(size_t size) : data(size) {}// 非常量版本,允许修改int& operator[](size_t index) {if (index >= data.size()) {throw out_of_range("Index out of range");}return data[index];}// 常量版本,只读访问const int& operator[](size_t index) const {if (index >= data.size()) {throw out_of_range("Index out of range");}return data[index];}size_t size() const { return data.size(); }
};int main() {IntArray arr(5);// 使用[]赋值for (size_t i = 0; i < arr.size(); ++i) {arr[i] = i * 10;}// 使用[]读取for (size_t i = 0; i < arr.size(); ++i) {cout << arr[i] << " ";}// 输出: 0 10 20 30 40// 常量对象使用const IntArray carr(3);cout << carr[0];  // 使用const版本return 0;
}

跳转返回——多态

类成员访问运算符->

#include <iostream>
using namespace std;class Data {
public:int value;Data(int v) : value(v) {}void print() { cout << "Value: " << value << endl; }
};class DataPtr {Data* ptr;
public:DataPtr(Data* p) : ptr(p) {}~DataPtr() { delete ptr; }// 重载->运算符Data* operator->() { return ptr; }const Data* operator->() const { return ptr; }
};int main() {DataPtr dp(new Data(42));dp->print();       // 实际调用: dp.operator->()->print()dp->value = 100;   // 访问成员变量const DataPtr cdp(new Data(200));cdp->print();      // 使用const版本return 0;
}

跳转返回——多态


多态实例

#include <iostream>
using namespace std;// 基类 Shape,表示形状
class Shape {protected:int width, height; // 宽度和高度public:// 构造函数,带有默认参数Shape(int a = 0, int b = 0) : width(a), height(b) { }// 虚函数 area,用于计算面积// 使用 virtual 关键字,实现多态virtual int area() {cout << "Shape class area: " << endl;return 0;}
};// 派生类 Rectangle,表示矩形
class Rectangle : public Shape {public:// 构造函数,使用基类构造函数初始化 width 和 heightRectangle(int a = 0, int b = 0) : Shape(a, b) { }// 重写 area 函数,计算矩形面积int area() override { cout << "Rectangle class area: " << endl;return width * height;}
};// 派生类 Triangle,表示三角形
class Triangle : public Shape {public:// 构造函数,使用基类构造函数初始化 width 和 heightTriangle(int a = 0, int b = 0) : Shape(a, b) { }// 重写 area 函数,计算三角形面积int area() override { cout << "Triangle class area: " << endl;return (width * height / 2); }
};// 主函数
int main() {Shape *shape;           // 基类指针Rectangle rec(10, 7);   // 矩形对象Triangle tri(10, 5);    // 三角形对象// 将基类指针指向矩形对象,并调用 area 函数shape = &rec;cout << "Rectangle Area: " << shape->area() << endl;// 将基类指针指向三角形对象,并调用 area 函数shape = &tri;cout << "Triangle Area: " << shape->area() << endl;return 0;
}

相关文章:

  • MVC/MVVM 高级应用的深度解析
  • 深入理解 Linux 权限管理:从 Shell 到文件权限
  • PyTorch生成式人工智能实战(1)——神经网络与模型训练过程详解
  • pytorch学习02
  • 人工智能 - browser-use:重新定义浏览器自动化的 AI 新范式
  • 【Leetcode 每日一题 - 补卡】2537. 统计好子数组的数目
  • 【Kubernetes基础--Service深入理解】--查阅笔记4
  • LeetCode【剑指offer】系列(位运算篇)
  • 观察者模式:从博客订阅到消息队列的解耦实践
  • 【面试向】梯度消失和梯度爆炸,激活函数?权重初始化?归一化?
  • Actor-Critic(演员评论家算法)基础解析与代码实例:稳定倒立摆
  • Mac idea WordExcel等文件git modify 一直提示修改状态
  • NoSQL 与 NewSQL 全面对比:如何选择适合你的数据库方案?
  • 1.Axum 与 Tokio:异步编程的完美结合
  • 聊聊Spring AI Alibaba的PdfTablesParser
  • 机器学习简介
  • 【LeetCode Solutions】LeetCode 166 ~ 169 题解
  • vue2.x Echart label根据数据长度选择不同的间隔显示
  • VSTO幻灯片退出播放(C#模拟键盘鼠标的事件)
  • 股指期货怎样选择换月时点?
  • 商务部就美国商务部调整芯片出口管制有关表述答记者问
  • 上昆“学馆制”10年,完成300出折子戏和20台大戏传承
  • 天问二号探测器顺利转入发射区
  • 以军证实空袭也门多个港口
  • 商务部回应稀土出口管制问题
  • 新任国防部新闻发言人蒋斌正式亮相