CppGC objects support prototype-based inheritance mirroring JavaScript's class Child extends Parent.
Requirements
- All types in the chain must use
#[repr(C)]. - The base type must be the first field of the derived struct (offset 0).
- Leaf types: Use
#[derive(CppgcInherits)]. - Root base types: Use
#[derive(CppgcBase)] and #[op2(base)] on the impl block. - Intermediate types: Use both
#[derive(CppgcInherits, CppgcBase)] and #[op2(base, inherit = ParentType)]. - Registration: Register all types in the extension's
objects list, with base types listed before derived types.
Example: Base and Derived Classes
// Base Class
#[derive(CppgcBase)]
#[repr(C)]
pub struct Shape {
sides: GcCell<u32>,
}
#[op2(base)]
impl Shape {
#[constructor]
#[cppgc]
fn new(sides: u32) -> Shape { ... }
}
// Derived Class
#[derive(CppgcInherits)]
#[cppgc_inherits_from(Shape)]
#[repr(C)]
pub struct Rectangle {
base: Shape, // Must be first
width: GcCell<f64>,
height: GcCell<f64>,
}
#[op2(inherit = Shape)]
impl Rectangle {
#[constructor]
#[cppgc]
fn new(width: f64, height: f64) -> Rectangle { ... }
}
// Base Class
#[derive(CppgcBase)]
#[repr(C)]
pub struct Shape {
sides: GcCell<u32>,
}
#[op2(base)]
impl Shape {
#[constructor]
#[cppgc]
fn new(sides: u32) -> Shape {
Shape { sides: GcCell::new(sides) }
}
#[getter]
fn sides(&self, isolate: &v8::Isolate) -> u32 {
*self.sides.get(isolate)
}
}
// Derived Class
#[derive(CppgcInherits)]
#[cppgc_inherits_from(Shape)]
#[repr(C)]
pub struct Rectangle {
base: Shape, // Must be first
width: GcCell<f64>,
height: GcCell<f64>,
}
#[op2(inherit = Shape)]
impl Rectangle {
#[constructor]
#[cppgc]
fn new(width: f64, height: f64) -> Rectangle {
Rectangle {
base: Shape { sides: GcCell::new(4) },
width: GcCell::new(width),
height: GcCell::new(height),
}
}
#[fast]
fn area(&self, isolate: &v8::Isolate) -> f64 {
*self.width.get(isolate) * *self.height.get(isolate)
}
}