How to Simulate C++ Inheritance Mechanisms

โš“ Rust    ๐Ÿ“… 2025-11-20    ๐Ÿ‘ค surdeus    ๐Ÿ‘๏ธ 10      

surdeus

Recently, I've been rewriting some C++ open-source libraries in Rust. Due to the inheritance relationships present in the original C++ code, I need to simulate inheritance for a small number of structs in Rust. I cannot fully rely on trait + struct implementations (as this would require library users to write a significant amount of boilerplate code manually). Therefore, I have no choice but to attempt simulating C++ inheritance in Rust, though this simulation doesn't need to be overly complex.

Iโ€™m seeking help here and would like to ask: Can procedural macros be used to simulate C++ inheritance mechanisms? If procedural macros can achieve this simulated inheritance, please provide some rough implementation ideas. Thank you in advance!

Additional note: I prefer not to use the newtype or delegate mechanisms, as Iโ€™m concerned they might introduce slight runtime performance overhead. Moreover, they could negatively impact code readability, especially since this is not a greenfield project but a rewrite of an existing C++ codebase.

Hereโ€™s a rough idea of what Iโ€™d like to achieve using procedural macros:

  • Define a public interface using trait xxx, and also define a struct named struct xxx_impl_boilerplate that implements trait xxx and contains some fields. struct xxx_impl_boilerplate will act as the base class in C++. For example:
pub trait xxx {
    fn name(&self) -> &str;
}

pub struct xxx_impl_boilerplate {
    name: String,
}

impl xxx for xxx_impl_boilerplate {
    fn name(&self) -> &str {
        &self.name
    }
}
  • Define a derived struct struct yyy that "inherits" trait xxx. With the help of a procedural macro, the implementation code and fields from struct xxx_impl_boilerplate should be copied into struct yyy. The resulting code should resemble the following handwritten version:
pub struct yyy {
    name: String,
    // Other fields...
}

// The procedural macro should automatically generate this code...
impl xxx for yyy {
    fn name(&self) -> &str {
        &self.name
    }
}
  • If a method with the same name (e.g., fn name(&self) -> &str) appears in the impl block of struct yyy, the procedural macro should replace the method in impl xxx for yyy with the one from struct yyy's impl block. This mimics C++โ€™s override behavior. The syntax sugar might look like this:
#[inherit(xxx from xxx_impl_boilerplate)]
pub struct yyy {
    name: String,
    // Other fields...
}

impl yyy 
{
    #[override]
    fn name(&self) -> &str {
        // ...
    }
}

These are just my preliminary thoughts. Are there better approaches to simulating C++ inheritance mechanisms? Thank you again for your help!

2 posts - 2 participants

Read full topic

๐Ÿท๏ธ Rust_feed