☰
c++的静态类型和动态类型(二)
2026/10/8 7:01:45 网站建设 项目流程

本文有两处小细节可以更严谨:

  1. "静态类型语言"之外的补充:下文里说"在使用基类指针/引用时才会涉及动态类型",这是常见的实用说法。严格按标准,glvalue 的动态类型指它所引用的最派生对象的类型,只是对非多态类来说你无法通过typeid/dynamic_cast观察到它。
  2. Derived::bar()的写法:它隐藏(hide)了Base::bar,而不是重写。这个例子本来就是想演示"非虚函数按静态类型选择",所以没问题,只是如果想学习,值得明确说一句"这是隐藏,不是覆盖"。

C++ 的静态类型和动态类型

C++ 是静态类型语言:变量、表达式、函数参数等的类型在编译期就确定了,这叫静态类型。

同时,C++ 通过继承 + 虚函数支持运行期多态,所以在使用基类指针/引用操作对象时,才会涉及动态类型:对象在运行时实际是什么类型。

看例子:

#include<iostream>#include<typeinfo>classBase{public:virtual~Base()=default;// 有虚函数,Base 是多态类型virtualvoidfoo()const{std::cout<<"Base::foo\n";}voidbar()const{std::cout<<"Base::bar\n";}};classDerived:publicBase{public:voidfoo()constoverride{std::cout<<"Derived::foo\n";}voidbar()const{std::cout<<"Derived::bar\n";}voidextra()const{std::cout<<"Derived::extra\n";}};intmain(){Derived d;Base*p=&d;// p 的静态类型是 Base*// *p 的静态类型是 Base// *p 的动态类型是 DerivedBase&r=d;// r 的静态类型是 Base&// r 的动态类型是 Derivedp->foo();// 输出 Derived::foo,虚函数按动态类型调用p->bar();// 输出 Base::bar,非虚函数按静态类型调用r.foo();// 输出 Derived::foo// p->extra(); // 编译错误!编译器只看静态类型 Base*,看不到 extraif(typeid(*p)==typeid(Derived)){std::cout<<"p 指向的对象动态类型是 Derived\n";}if(Derived*q=dynamic_cast<Derived*>(p)){q->extra();// 输出 Derived::extra}Base b=d;// 对象切片:b 的静态类型和动态类型都是 Baseb.foo();// 输出 Base::foo}

核心区别

概念静态类型动态类型
确定时机编译期运行期
依据变量/表达式声明类型指针/引用实际指向的对象类型
用途类型检查、重载解析、模板、非虚函数调用虚函数分派、typeid、dynamic_cast
例子Base* p的静态类型是Base*p指向Derived时,*p的动态类型是Derived

一句话总结:

静态类型是编译器看到的类型;动态类型是运行时对象真正的类型。
在 C++ 中,动态类型主要通过虚函数和RTTI起作用。



小写字母a的 ASCII 编码值是:

  • 十进制:97
  • 十六进制:0x61
  • 八进制:141
  • 二进制:01100001

补充:大写字母A的 ASCII 值是65。在常见 C++ 实现中,int('a') == 97;不过 C++ 标准本身不强制一定使用 ASCII,但主流平台基本都是 ASCII/UTF-8 兼容。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询