Add common base class for opaque Rust types
diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs
index 35620db..621d88c 100644
--- a/gen/src/builtin.rs
+++ b/gen/src/builtin.rs
@@ -12,6 +12,7 @@
     pub rust_vec: bool,
     pub rust_fn: bool,
     pub rust_isize: bool,
+    pub opaque: bool,
     pub unsafe_bitcopy: bool,
     pub rust_error: bool,
     pub manually_drop: bool,
@@ -120,6 +121,7 @@
     ifndef::write(out, builtin.rust_fn, "CXXBRIDGE1_RUST_FN");
     ifndef::write(out, builtin.rust_error, "CXXBRIDGE1_RUST_ERROR");
     ifndef::write(out, builtin.rust_isize, "CXXBRIDGE1_RUST_ISIZE");
+    ifndef::write(out, builtin.opaque, "CXXBRIDGE1_RUST_OPAQUE");
     ifndef::write(out, builtin.relocatable, "CXXBRIDGE1_RELOCATABLE");
 
     if builtin.manually_drop {
diff --git a/gen/src/write.rs b/gen/src/write.rs
index a12af31..66d6351 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -232,13 +232,8 @@
     for line in ety.doc.to_string().lines() {
         writeln!(out, "//{}", line);
     }
-    writeln!(out, "struct {} final {{", ety.name.cxx);
-    writeln!(out, "  {}() = delete;", ety.name.cxx);
-    writeln!(
-        out,
-        "  {}(const {} &) = delete;",
-        ety.name.cxx, ety.name.cxx,
-    );
+    out.builtin.opaque = true;
+    writeln!(out, "struct {} final : public ::rust::Opaque {{", ety.name.cxx);
     for method in methods {
         write!(out, "  ");
         let sig = &method.sig;
diff --git a/include/cxx.h b/include/cxx.h
index 204f6a9..0632f22 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -296,6 +296,16 @@
 std::ostream &operator<<(std::ostream &, const String &);
 std::ostream &operator<<(std::ostream &, const Str &);
 
+#ifndef CXXBRIDGE1_RUST_OPAQUE
+#define CXXBRIDGE1_RUST_OPAQUE
+// Base class of generated opaque Rust types.
+class Opaque {
+  Opaque() = delete;
+  Opaque(const Opaque &) = delete;
+  ~Opaque() = delete;
+};
+#endif // CXXBRIDGE1_RUST_OPAQUE
+
 // IsRelocatable<T> is used in assertions that a C++ type passed by value
 // between Rust and C++ is soundly relocatable by Rust.
 //