本篇笔记系统性地整理了C++面向对象编程的核心概念,涵盖了从基础封装、构造函数/析构函数,到高级特性如继承、多态、模板、容器等关键内容,并辅以代码示例,适合学习和回顾。
封装
核心概念
- 核心思想:将数据与操作数据的函数绑定在一个结构(类)中,实现信息隐藏和数据安全。
- 类 (
class) :相当于C语言的结构体的升级,可包含成员变量和成员函数。
访问权限控制:
public:公有,类内外部均可访问。
private:私有,仅本类内部可访问。
protected:受保护,本类和派生类可访问。
class base//类定义
{
public://公有
int a;
int b;
void Init()
{
this->a = 1;
this->b = 2;
this->c = 3;
this->d = 4;
}
int add();//声明 定义在下面
private://私有
int c;
protected://受保护
int d;
}
// 成员函数在类外定义
int base::add()//打个标签 base对象里面的
{
return this.a + this.b;
}
int main()
{
base test;
test.Init();
test.a = 100;
return 0;
};
核心要点
- 结构体首地址给
ecxthis—>[ebp-0x4] - 成员函数不占用类的对象空间,只存储一份代码。
- 反汇编中,对象会多分配4个字节(32位)用于存储
this指针(通常位于[EBP-0x4]),这时候,第1个变量是[EBP-0x8]开始,依次类推 - C++过程中只要对本对象操作的函数 全部都要封装在一起
构造函数与析构函数
构造函数
功能:对象创建时自动调用,用于初始化成员变量。
特点:
- 函数名与类名完全相同。
- 无返回值类型。
- 参数可有,可没有
- 构造函数传参的时候,先判断参数个数,在判断参数类型
- 无参数的构造函数称为缺省构造函数。
class base
{
public://公有
int a;
int b;
base(int x, int y)
{
this->a = x;
this->b = y;
}
base();//定义构造函数
}
base::base()//缺省的构造函数
{
}
int main()
{
base test(2,3);
return 0;
};
多个构造函数:
- 看参数的个数
- 如果参数的个数一样,在看参数的类型
class base
{
public://公有
int a;
int b;
char c;
base(int x, int y);
base(int x, char y);
}
base::base(int x, int y)
{
this->a = x;
this->b = y;
}
base::base(int x, char y)
{
this->a = x;
this->c = y;
}
int main()
{
base test(2,3);
base test(2,'A');
return 0;
};
析构函数
功能:对象销毁(生命周期结束)时自动调用,用于清理资源。
特点:
- 函数名为类名前加波浪线
~。 - 释放对象,有多少对象,就释放多少次
- 函数名与类名完全相同。
- 无返回值,无参数。
- 一个类有且只有一个析构函数。
class base
{
public://公有
int a;
int b;
char c;
base(int x, int y)//构造函数
{
this->a = x;
this->b = y;
}
~base()//析构函数
{
cout << "释放了" << endl;
}
}
int main()
{
base test(2,3);
base test(2,'A');
return 0;
};
继承
核心概念
- 继承:派生类(子类)继承基类(父类)的成员,实现代码复用和层次化设计。他的成员变量是放在对象的最上面,第1个继承的对象,始终在最上面,只要继承了那就是派生类。
- 派生类对象的内存布局中,基类成员位于最上方。
- 继承方式:
public,protected,private。
#include <iostream>
//父亲 基类 父类
class student1
{
//公有
public:
int a;
//私有 只有本对象可以用
private:
int e;
//受保护 可以被继承
protected:
int g;
};
//母亲 基类 父类
class student2
{
public://公有
int f;
};
//儿子 派生类 子类 继承多个打逗号student1和student2
class student:public student1,public student2
{
public://公共
int a;
int b;
int c;
};
int main()
{
student aa;
aa.a = 1;;//ebp-0xC
aa.b = 2;//ebp-0x8
aa.c = 3;//ebp-0x4
aa.student1::a = 1;//ebp-0x14 加作用域代表哪个对象里面
aa.f = 5;//ebp-0x10
return 0;
}
继承构造函数
- 派生类可调用基类构造函数初始化继承来的成员。
#include <iostream>
using namespace std;
class base
{
//公有
public:
int a;
int b;
base()
{
}
base(int x,int y)
{
this->a = x;
this->b = y;
}
~base()
{
}
};
class student: public base
{
public:
student(int d,int e,int g):base(d,e),f(g)//继承base析构函数 初始化 只有继承了 才使用f(g)赋值方式
{
}
~student()
{
}
void init()
{
cout << this->a << endl << this->b << endl << this->f << endl;
}
private:
int f;
};
int main()
{
base aa;
student bb(1,2,3);
bb.init();
return 0;
}
运算符重载
- 关键字:
operator,后面加运算符 (简单来说就是给函数名字 起个名字) - 功能:为用户自定义类型(类)重新定义运算符的行为。
#include <iostream>
using namespace std;
class base
{
public:
int a;
int b;
base(int i1,int i2)//构造函数
{
this->a = i1;
this->b = i2;
}
~base()//析构函数
{
}
void operator-(int c)//运算符重载
{
c = this->a - this->b;
cout << c << endl;
}
void operator+(int c)//运算符重载
{
c = this->a + this->b;
cout << c << endl;
}
};
int main()
{
int r = 0;
base aa(1,2);
aa.operator+(r);
return 0;
}
模板
函数模板
- 关键字:
template<typename/class name> - 功能:编写与数据类型无关的通用函数。
#include <iostream>
using namespace std;
//函数模板
template<typename temp,typename temp1>
temp add(temp a, temp1 b)
{
temp c;
c = a + b;
cout << "add: "<< c << endl;
return c;
}
int main()
{
add(1,2);
add((short)1,(short)2);
add((long)10000000,(long)20000000);
return 0;
}
类模板
- 功能:定义可处理多种数据类型的通用类。
- 每个函数都要加上模板
- 告诉它处理什么类型数据的放括号里面
<T> - 定义类的时候要传入类型告知是
int char short类型Stack<char> s; - 注意:每个成员函数定义前都需再次声明模板。
#include <iostream>
#include <cstdlib>
using namespace std;
template<typename T>//每个函数都加上
class Stack
{
typedef struct node
{
T value;
struct node* pnext;
}NODE,*PNODE;
public:
void init();
void push(T value);
void show();
private:
PNODE s_esp;
PNODE s_ebp;
};
template<typename T>//每个函数都加上
void Stack<T>::init()
{
this->s_esp = this->s_ebp =(PNODE)malloc(sizeof(NODE));
if (this->s_esp == NULL)
{
cout << "分配内存失败!" << endl;
}
this->s_ebp->pnext = NULL;
}
template<typename T>//每个函数都加上
void Stack<T>::push(T value)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if (pNew == NULL)
{
cout << "分配内存失败!" << endl;
}
pNew->value = value;
pNew->pnext = this->s_esp;
this->s_esp = pNew;
}
template<typename T>//每个函数都加上
void Stack<T>::show()
{
PNODE p = this->s_esp;
while ( p != this->s_ebp )
{
cout << p->value << endl;
p = p->pnext;
}
}
int main()
{
Stack<char> s;//可以传char int long char*...
s.init();
s.push('A');
s.push('B');
s.push('C');
s.push('D');
s.push('E');
s.show();
return 0;
}
命名空间
- 功能:避免命名冲突,将全局作用域划分为不同的区域。
- 关键字:
namespace,using
#include <iostream>
//using std::cout;
//using std::cin;
//using std::endl;
//自己定义的命名空间
namespace myname
{
int res;
int add(int a, int b)
{
return a + b;
}
class student
{
public:
int a;
};
}
//所有东西都是放在这里std命名空间里面 这样就调用就不需要加上std::
using namespace std;
//放到命名空间里面 下面就不需要加上myname::进行访问了
using namespace myname;
int main()
{
// res = myname::add(1, 2);
res = add(1, 2);
// myname::student aa;
// aa.a = 88;
student aa;
aa.a = 88;
cout << res << "\t" << aa.a << endl;
char str[20];
cout << "命名空间" << endl;
cin >> str;
cout << str << endl;
return 0;
}
虚函数与多态
虚函数
- 关键字:
virtual - 功能:实现运行时多态。通过基类指针或引用调用派生类的重写函数。
- 原理:包含虚函数的类会增加一个虚表指针 (vptr),指向一个虚函数表 (vtable),表中存放实际的函数地址。
核心要点
- 什么是虚函数:在函数的前面加上
virtual - 用基类去访问派生类,函数原型要一样
- 虚函数多分配的四字节,放的是虚表指针
- 虚表指针里面放的是,函数的地址(派生类)
- 虚函数只能在对象里面的函数加 构造函数不能加 全局变量不能加
#include <iostream>
using namespace std;
//基类
class base
{
public:
int value;
virtual void fun()//虚函数
{
printf("基类--->base fun调用\n");
}
};
//派生类
class student:public base
{
public:
int value;
virtual void fun()//虚函数 可加可不加 virtual
{
printf("派生类--->student fun调用\n");
}
};
int main()
{
student aa;
base* bb;
bb = &aa;
bb->fun();
printf("base = %d\tstudent = %d\n",sizeof(base),sizeof(student));
return 0;
}
纯虚函数与抽象类
- 纯虚函数:
virtual void fun() = 0; - 抽象类:包含至少一个纯虚函数的类。不能实例化对象,仅为派生类提供接口规范。
- 纯虚函数:父类(基类)没有完成的事情交给子类(派生类)去完成
class base
{
public:
int a;
virtual void fun() = 0;//纯虚函数
}
class student:public base
{
virtual void fun()
{
cout << "被调用了" << endl;
}
};
多态应用示例
#include <iostream>
#include <string>
using namespace std;
//动物
class base
{
public:
virtual void init()
{
cout << "base init--->被调用了" << endl;
}
virtual void put()
{
cout << "base put--->被调用了" << endl;
}
};
class Cat : public base
{
public:
string name;
virtual void init()
{
this->name = "猫";
}
virtual void put()
{
cout << "动物名字: " << this->name << endl;
}
};
class Sheep : public base
{
public:
string name;
virtual void init()
{
this->name = "羊";
}
virtual void put()
{
cout << "动物名字: " << this->name << endl;
}
};
class Ox : public base
{
public:
string name;
virtual void init()
{
this->name = "牛";
}
virtual void put()
{
cout << "动物名字: " << this->name << endl;
}
};
class Dog : public base
{
public:
string name;
virtual void init()
{
this->name = "狗";
}
virtual void put()
{
cout << "动物名字: " << this->name << endl;
}
};
class Crocodile : public base
{
public:
string name;
virtual void init()
{
this->name = "鸟";
}
virtual void put()
{
cout << "动物名字: " << this->name << endl;
}
};
int main()
{
Cat aa;
Sheep bb;
Ox cc;
Dog dd;
Crocodile ee;
base* animal[] = { &aa,&bb,&cc,&dd,&ee };
int i;
for ( i = 0; i < sizeof(animal)/sizeof(base*); i++ )
{
animal[i]->init();
animal[i]->put();
cout << endl;
}
return 0;
}
STL容器
核心容器简介:
vector:动态数组。插入/删除数据慢,支持随机访问,查找和排序快。list:双向链表。在任何位置插入/删除都快,但不支持随机访问。deque:双端队列。综合能力强,两端插入/删除快。
vector 基本用法
#include <iostream>
#include <vector>
#include <string>
int main()
{
using namespace std;
//定义容器
vector<int> v1;
//定义容器 默认的初始化为0
vector<string> v2(10);
//定义容器 传对象的时候类型必须一样
vector<string>v3(v2);
//定义容器 b[10] = {2,2,2,2,2,2,2,2,2,2};
vector<int> v4(10, 2);
//添加数据
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
//遍历数据 常规
for (vector<int>::size_type i = 0; i < v1.size(); i++)
{
cout << v1[i] << endl;
}
//循环添加数据
for (vector<int>::size_type i = 0; i < 5; i++)
{
// cin >> v1[i]; //C++不允许这么操作
// cin >> i;
v1.push_back(i);
}
//遍历数据 指针
for (vector<int>::iterator p = v1.begin(); p != v1.end(); p++)
{
cout << *p << endl;
}
return 0;
}
文件流
核心类
- ofstream:输出文件流,用于写文件(派生自ostream)。
- ifstream:输入文件流,用于读文件(派生自istream)。
- fstream:输入输出文件流,用于读写文件(派生自iostream)。
![图片[1]-C++核心知识点整理笔记-萝莉猫博客](https://www.luolimao.com/wp-content/uploads/2026/03/20260301123007745-文件流关系.png)
文件打开模式
| 模式常量 | 含义 |
| ios_base::in | ios_base::in |
| ios_base::out | 打开文件,用于写入 |
| ios_base::ate | 打开文件立即将文件定位在文件尾 |
| ios_base::app | 追加模式,写入到文件末尾 |
| ios_base::trunc | 打开时清空文件内容 |
| ios_base::binary | 以二进制模式打开 |
注意:out | app、app|trunc 不能共存
示例:读取文件
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream file("data.txt"); // 默认以 in 模式打开
string s;
if(!file) { cerr << "打开文件失败!" << endl; }
file >> s; // 读取一个字符串
cout << s << endl;
file.close();
return 0;
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END







暂无评论内容