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

python中class与C++class的区别和联系

Python 和 C++ 的class看似都是面向对象的核心语法,但因语言设计哲学(静态编译 vs 动态解释)、内存模型、运行时机制的本质差异,二者在定义、属性、方法、调用、运行原理等层面都有显著区别。下面我会从 6 个核心维度全面拆解,结合代码示例和底层原理讲清楚差异。

一、定义层面:静态模板 vs 动态对象

1. C++:编译期静态模板(无运行时实体)
  • 本质:C++ 的class编译期的类型蓝图 / 模板,仅定义 “实例该如何分配内存、成员函数该如何绑定”,编译后类本身不占用内存,只有实例才会分配内存。
  • 定义规则
    • 必须显式声明成员的访问权限(public/private/protected,默认private);
    • 类定义需以;结尾;
    • 编译期检查语法和类型,错误在编译阶段暴露。

示例

cpp

运行

// C++ 类定义 class CLanguage { private: // 显式权限控制(默认private) int id; // 仅定义实例内存偏移量,无实际存储 public: string name; // 成员函数声明(可在类内/外实现) void show(); }; // 成员函数实现(类外需加作用域解析符::) void CLanguage::show() { cout << name << endl; }
2. Python:运行时动态对象(类本身是对象)
  • 本质:Python 的class运行时创建的 “类对象(class object)”,本身占用内存(存储属性、方法的__dict__字典),定义类的过程就是创建 “类对象” 的过程。
  • 定义规则
    • 无显式访问权限关键字(靠命名约定:_xxx私有、__xxx名称改写);
    • 类定义无需;结尾;
    • 语法和类型检查延迟到运行时,错误在执行阶段暴露。

示例

python

运行

# Python 类定义 class CLanguage: # 无权限关键字,_id 靠约定表示私有 _id = 1 name = "C++教程" # 挂载到类对象的__dict__中 # 方法直接定义在类内 def show(self): print(self.name) # 运行时动态查看类对象的属性 print(CLanguage.__dict__) # 输出类的所有属性/方法

二、属性层面:静态绑定 vs 动态挂载

表格

维度C++ 类属性Python 类属性
分类普通成员变量(实例独有)、静态成员变量(类共享)、常量(const类属性(类对象共享)、实例属性(实例独有)、动态添加属性
内存存储普通属性:实例内存(编译期确定偏移量);静态属性:全局内存类属性:类对象的__dict__;实例属性:实例的__dict__
访问控制public/private/protected强制控制靠命名约定(_xxx/__xxx)弱控制(可通过_类名__xxx突破)
动态性编译期固定,无法动态添加 / 删除成员(除非用扩展)运行时可动态添加 / 删除:CLanguage.new_attr = 123
初始化普通属性:构造函数__init__(C++ 是ClassName())初始化;静态属性:类外显式初始化类属性:类定义时初始化;实例属性:__init__中初始化

示例对比

cpp

运行

// C++ 属性 class CLanguage { public: string name; // 普通属性:仅定义结构,无存储 static int version; // 静态属性:需类外初始化 const int type = 1; // 常量:C++11后可类内初始化 }; // 静态属性必须类外初始化 int CLanguage::version = 20; int main() { CLanguage obj; obj.name = "C++"; // 实例初始化属性 // CLanguage::new_attr = 123; // ❌ 无法动态添加属性 return 0; }

python

运行

# Python 属性 class CLanguage: version = 20 # 类属性:存储在类对象__dict__ def __init__(self): self.name = "C++" # 实例属性:存储在实例__dict__ # 运行时动态添加类属性 CLanguage.new_attr = 123 obj = CLanguage() # 动态添加实例属性 obj.age = 30 print(CLanguage.new_attr) # 输出:123 print(obj.age) # 输出:30

三、方法层面:静态绑定 vs 动态关联

表格

维度C++ 类方法Python 类方法
分类普通成员函数、静态成员函数、虚函数(多态)、纯虚函数(抽象类)实例方法、静态方法(@staticmethod)、类方法(@classmethod
隐含参数普通方法:this指针(编译期隐式传入);静态方法:无实例方法:self(运行时显式传入);类方法:cls;静态方法:无
多态实现靠虚函数表(vtable)编译期 / 运行时绑定(静态多态 / 动态多态)靠方法重写 + 运行时查找(鸭子类型,无虚函数概念)
方法重载支持(同名方法,参数列表不同)不支持(后定义的方法覆盖先定义的),需手动模拟
抽象类靠纯虚函数(virtual void func() = 0)实现abc模块的abstractmethod装饰器

示例对比

cpp

运行

// C++ 方法 class CLanguage { public: // 普通成员函数(隐含this指针) void show(string msg) { cout << msg << endl; } // 方法重载(参数不同) void show(int num) { cout << num << endl; } // 静态成员函数(无this指针) static void static_func() { cout << "静态方法" << endl; } // 虚函数(动态多态) virtual void poly_func() { cout << "父类多态方法" << endl; } }; // 子类重写虚函数 class CppLanguage : public CLanguage { public: void poly_func() override { // 显式override cout << "子类多态方法" << endl; } };

python

运行

# Python 方法 class CLanguage: # 实例方法(显式self) def show(self, msg): print(msg) # 无方法重载,后定义的覆盖前一个 def show(self, num): print(num) # 静态方法(无self/cls) @staticmethod def static_func(): print("静态方法") # 类方法(显式cls) @classmethod def class_func(cls): print(f"类方法:{cls.__name__}") # 多态(靠重写) def poly_func(self): print("父类多态方法") class CppLanguage(CLanguage): def poly_func(self): # 重写实现多态 print("子类多态方法")

四、格式与语法细节

表格

特性C++Python
类定义结尾必须加;无需;,靠缩进区分代码块
构造 / 析构函数构造:ClassName();析构:~ClassName()构造:__init__();析构:__del__()(非手动调用)
继承语法class 子类 : 权限 父类(如public CLanguageclass 子类(父类1, 父类2)(多继承默认)
作用域解析类外方法 / 静态成员:ClassName::func()::,直接ClassName.func()
空类空类占 1 字节(编译器为了区分地址)空类是完整的类对象,占用内存(存储__dict__等)

五、调用与使用方式

表格

场景C++ 调用方式Python 调用方式
普通属性 / 方法必须通过实例:obj.name/obj.func()实例:obj.name;类名:CLanguage.name(类属性)
静态成员类名:ClassName::static_var;实例:obj.static_var类名:ClassName.static_func();实例:obj.static_func()
构造实例ClassName obj;(栈)/new ClassName()(堆)obj = ClassName()(堆,自动垃圾回收)
方法参数实参无需传this(编译器隐式传)实例方法必须传self(解释器自动传)

六、运行机制与编译原理(核心根源)

这是二者所有差异的底层原因,也是最关键的部分:

1. C++:静态编译型,编译期确定一切
  • 编译流程:源码 → 预处理 → 编译 → 汇编 → 链接 → 可执行文件(二进制)。
    • 编译期:编译器解析类定义,确定实例内存布局(成员变量偏移量)、成员函数的代码地址,绑定静态成员的全局内存;
    • 运行期:仅加载二进制文件,类已不存在,只有实例的内存和函数的代码段,所有调用都是 “地址跳转”,无动态查找。
  • 内存效率:极致高效,实例仅存储成员变量,成员函数共享代码段;
  • 灵活性:差,编译期固定,无法动态修改类结构。
2. Python:动态解释型,运行时动态解析
  • 执行流程:源码 → 解释器(CPython 先编译为字节码)→ 虚拟机执行。
    • 定义类时:解释器创建 “类对象”,将属性 / 方法存入__dict__,类本身是可访问、可修改的对象;
    • 调用属性 / 方法时:解释器动态查找__dict__(实例 → 类 → 父类),找到后执行;
  • 内存效率:较低,类和实例都有__dict__字典,方法调用需动态查找;
  • 灵活性:极高,运行时可动态添加 / 删除类 / 实例的属性、方法,甚至修改继承关系。

总结

Python 和 C++ 的class核心差异源于语言设计的底层逻辑:

  1. 本质差异:C++ 的类是编译期静态模板(无运行时实体),Python 的类是运行时动态对象(占用内存、可修改);
  2. 核心机制:C++ 靠编译期绑定内存地址实现高效访问,Python 靠运行时查找__dict__实现灵活调用;
  3. 设计取舍:C++ 牺牲灵活性换内存 / 执行效率,Python 牺牲效率换动态性和易用性;
  4. 语法表现:C++ 有严格的权限控制、方法重载、虚函数等静态特性,Python 靠约定和动态查找实现面向对象,无强制静态约束。

简单来说:C++ 的类是 “死的模板”,编译后就定型;Python 的类是 “活的对象”,运行时还能改。

http://www.jsqmd.com/news/507444/

相关文章:

  • 终极指南:MS-DOS批处理变量使用与早期脚本参数传递技巧
  • 基频检测算法总结
  • Zig核心特性深度解析:为何它能替代C成为系统编程新宠
  • 如何轻松实现微信聊天记录从JSON到PDF的完整转换:GitHub_Trending/we/WeChatMsg终极指南
  • 深入解析Python的glob.glob()函数:高效递归匹配文件与目录的实战技巧
  • 海康威视DS-2CD2T2HY-LP1刷机固件包|含专用刷机工具+通用版固件|支持强刷救砖|终身可重复使用
  • Navicat Premium连接Oracle 11g保姆级教程(附instantclient配置避坑指南)
  • BackInTime 开源项目安装与使用指南
  • UR5机械臂实战:不依赖MoveIt的直接ROS控制方法(Python示例)
  • 100套前端可视化模板合集:支持HTML与Vue双架构,集成高德地图+百度ECharts图表
  • TF-IDF vs Word2Vec:如何根据你的项目需求选择合适的文本表示方法?
  • 探秘UI宝盒:18个顶级UI片段让你的前端开发效率提升300%
  • Discord 图片日志记录器使用教程
  • Dioxus国际化方案:构建多语言支持的全球应用
  • Postgres与Mybatis高效批量操作实战:从基础到高级冲突处理
  • 为什么老项目必须升级Apache Commons Collections?从CC1链看第三方库的安全风险
  • RAG分块策略实战:5种方法代码对比与性能测试(含GPT-4分块技巧)
  • 从克尔效应到频谱展宽:用Lumerical INTERCONNECT可视化SPM全流程
  • PVE 2.5G网卡性能优化:从通用驱动r8169到专用驱动r8125的实战迁移
  • H3C三层链路聚合实战:路由场景下的高可用配置与故障恢复
  • HarmonyOS 6实战:简单列表折叠和展开
  • 终极Lorri教程:如何简化Nix Shell管理并提升开发效率
  • 东南亚市场推广营销服务商哪家好?精选上海、苏州地区5家优质海外营销推广代运营公司(附带联系方式) - 品牌2026
  • Messenger 开源项目教程
  • Python-100-Days随机过程:概率模型与蒙特卡洛方法完全指南
  • plc教程 厚俊霞 叶强 小羽等全套PLC教程||| 叶强plc编程,叶强自动化 PLC全套编程学习
  • 2026年全国新房装修公司榜单 覆盖全屋整装智能装修 实力与口碑兼具 - 深度智识库
  • Docker镜像加速终极指南:2024年国内最稳镜像源推荐(附详细配置步骤)
  • 超强电商框架Medusa:支持B2B/DTC/市场/PoS全场景解决方案
  • Python-100-Days实战案例:从零打造简易文本编辑器