硬件端之C++中class的所有常见写法、类
MENU
- 01、最基础(声明vs定义、空类)
- 02、成员访问控制(类体内部)
- 03、继承(基本形式与访问说明)
- 04、多重继承
- 05、虚继承(解决菱形继承)
- 06、抽象类(纯虚函数)
- 07、virtual/override/final(方法层面)
- 08、final(类层面,禁止被继承)
- 09、构造函数继承/默认/删除
- 10、成员函数在类内定义vs类外定义
- 11、嵌套类/嵌套类型/friend
- 12、模板类(泛型)
- 13、虚析构函数的重要性
- 14、抽象接口风格(只含纯虚函数)
- 15、运算符重载、转换运算符等(类内写法)
- 16、聚合/标准布局/Trivial 类(写法相关提示)
- 17、其他特殊写法(快速列举)
- 19、小结(把最常见的变体列成一个对照表)
- 20、类定义写法速查表
01、最基础(声明vs定义、空类)
// 前向声明(声明,不分配内存,称为不完整类型) class A; // 定义(空类) class B {};
1、
class A;
,只是告诉编译器存在类型 A,不能实例化也不能访问成员,常用于指针/引用声明以减少头文件依赖。
2、class B {};
,完全定义类(称为空类),sizeof(B) >= 1(语言保证非零)。
02、成员访问控制(类体内部)
class C {private:int x;protected:int y;public:int z; };
1、private(类中默认)、protected、public控制成员可见性(方法、数据、嵌套类型、friend声明都受影响)。
2、struct的默认访问是public与class不同。
03、继承(基本形式与访问说明)
// 公有继承 class D : public Base {}; // 受保护继承 class E : protected Base {}; // 私有继承 class F : private Base {}; // 默认继承(class -> private,struct -> public) class G : Base {};
1、继承访问决定了基类的public、protected成员在派生类对外的可见性。
2、如果写成class X : Base
,默认相当于class X : private Base
(因为X用class声明)。如果是struct X : Base
,默认是public。
04、多重继承
class H : public Base1, private Base2 {};
1、允许从多个基类继承。
2、会产生二义性(若不同基类定义同名成员,使用时需要作用域限定或解决冲突)。
3、构造顺序:按基类在继承列表中出现的顺序构造,再构造成员,再构造派生类本身。
05、虚继承(解决菱形继承)
class Top {}; class Left : virtual public Top {}; class Right : virtual public Top {}; class Bottom : public Left, public Right {};
1、当存在“钻石”结构(Top是Left、Right的共同基类)时,若采用virtual继承,则Bottom只含有Top的一个共享子对象,避免重复数据成员与二义性。
2、virtual继承会带来额外开销(指针/偏移)并改变构造责任(最终派生类负责初始化虚基类)。
06、抽象类(纯虚函数)
class I {public:// 纯虚函数virtual void foo() = 0;// 虚析构函数(接口/基类推荐)virtual ~I() = default; };
1、含有至少一个纯虚函数的类称为抽象类,不能被实例化。
2、抽象类常用于接口(interface)设计。
3、纯虚函数可以在基类中提供实现(少见),但仍使类抽象:void I::foo() { /* ... */ }
,合法但I仍是抽象类。
07、virtual/override/final(方法层面)
class Base {public:virtual void f();// 派生类不可重写 g()virtual void g() final; };class Derived : public Base {public:// 编译器检查:必须覆盖基类的虚函数void f() override; };
1、virtual:函数可被重写并实现运行时多态。
2、override:显式表明这是覆盖基类虚函数,若不匹配基类签名会报错(非常推荐使用)。
3、final:禁止再被重写(方法)或禁止被继承(类)。
08、final(类层面,禁止被继承)
class NoDerive final {};// 错误 // class Sub : public NoDerive {};
1、final在类声明后面可以阻止其他类继承它(C++11引入)。
09、构造函数继承/默认/删除
class A {public:// 默认构造A() = default;// 禁止拷贝构造A(const A&) = delete;// 默认移动构造A(A&&) = default; };class B : public A {public:// 继承父类构造函数(C++11 起)using A::A; };
1、
= default;
,告诉编译器生成默认实现。
2、= delete;
,用于禁止某个函数(如拷贝/赋值),常用于不可拷贝的资源类(单例、句柄等)。
3、using Base::Base;
,允许派生类自动继承基类的构造函数(避免重复写构造转发)。
10、成员函数在类内定义vs类外定义
class K {public:// 在类内定义 -> 隐式 inlinevoid f() { /* inline body */ }void g(); };void K::g() { /* class外定义 */ }
1、类内定义的函数隐式是inline(仅影响链接,不代表编译器一定内联)。
2、类外定义需要写ClassName::method
的限定名。
11、嵌套类/嵌套类型/friend
class Outer {public:class Inner { /* 嵌套类 */ };friend class FriendClass;friend void friendFunc(Outer&); };
1、嵌套类是
Outer::Inner
,默认受private还是public取决于嵌套类所在的访问区(要把它写在public:
下才能外部直接访问)。
2、friend可授予外部函数或类访问私有成员的权限(破坏封装但有时必要)。
12、模板类(泛型)
template<typename T> class MyTemplate {public:T value; };template<> class MyTemplate<int> { /* 专门化 */ };
1、模板类允许类型参数化。
2、可以对特定类型做完全特化或偏特化(更高级)。
template<typename Derived> class BaseCRTP { /* 使用 Derived */ };class Derived : public BaseCRTP<Derived> {};
1、用于静态多态(编译期多态)与混入设计。
13、虚析构函数的重要性
class Base {public:virtual ~Base() {} };class Derived : public Base {};
1、如果基类打算通过基类指针删除派生类对象(Base* p = new Derived; delete p;),必须让基类析构函数为virtual,否则会导致资源泄漏或未定义行为。
14、抽象接口风格(只含纯虚函数)
struct IPrinter {virtual void print() = 0;virtual ~IPrinter() = default; };
struct+纯虚函数常用来定义接口(和class仅差别在默认可见性)。
15、运算符重载、转换运算符等(类内写法)
class Num {public:Num operator+(const Num& other) const;// 明确的转换运算符explicit operator int() const; };
1、常见把运算符重载作为类成员或自由函数来实现。
16、聚合/标准布局/Trivial 类(写法相关提示)
1、带有用户自定义构造函数或private成员或虚函数的类可能不是聚合类型。
2、聚合类型可以用于聚合初始化(T t{…})。
17、其他特殊写法(快速列举)
1、
class X final : public Y {};
:类不可被继承。
2、class X : public virtual Y {};
:虚继承(重复)。
3、class X : public Y, private Z {};
:混合继承访问。
4、class X { static int s; };
:静态成员(类级别)。
5、class X { using value_type = int; };
:嵌套类型别名。
6、class X { X() noexcept; };
:异常规格(现代通常用noexcept)。
19、小结(把最常见的变体列成一个对照表)
1、不继承、独立类
class A {};
2、单继承(显式访问)
class B : public Base {}; class C : protected Base {}; class D : private Base {};
3、多继承
class E : public B, private C {};
4、虚继承(解决菱形)
class F : virtual public Top {};
5、抽象类(接口)
class I { virtual void f() = 0; };
6、扩展语法,按需使用
final/override/= default/=delete/using Base::Base
/模板类/嵌套/friend等。
20、类定义写法速查表
表格
写法 名称/类型 说明 访问控制默认值 示例 class A {};
普通类 定义一个独立的类 private
class BleServer {};
class A;
前向声明 告诉编译器该类存在(不可实例化) — class BleServer;
class A : public B {};
公有继承 继承 B
的public
、protected
成员保持可访问private
class BleServer : public abc {};
class A : protected B {};
保护继承 继承的成员对外变为 protected
private
— class A : private B {};
私有继承 所有继承成员对外不可见 private
— struct A {};
结构体(类) 与 class 功能相同,只是默认访问为 public
public
— class A : virtual public B {};
虚继承 解决菱形继承重复基类问题 private
— class A : public B, private C {};
多重继承 同时继承多个基类 private
— class A final {};
禁止继承 A
不能再被其他类继承private
— class A : public B final {};
最终派生类 继承 B
,但不允许再有子类private
— class A { virtual void f() = 0; };
抽象类(接口) 含纯虚函数,不能实例化 private
— class A { A() = default; };
默认构造 编译器自动生成默认实现 private
— class A { A(const A&) = delete; };
删除函数 禁止拷贝或赋值等操作 private
— class A : public B { using B::B; };
继承构造函数 自动继承基类构造函数 private
— class A { friend class B; };
友元类 允许 B
访问A
的私有成员private
—
小结
1、class与struct的唯一区别:默认访问权限不同。
2、: public Base
=> 常用于继承接口或可替代的父类。
3、virtual => 用于支持多态;final => 用于禁止继承或重写。
4、= default、= delete => 控制构造/析构/拷贝的自动生成行为。