Delete private Box default constructor
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 4d8bc55..fc0872f 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1348,8 +1348,8 @@
     writeln!(out, "#define CXXBRIDGE1_RUST_BOX_{}", instance);
     writeln!(
         out,
-        "void cxxbridge1$box${}$uninit(::rust::Box<{}> *ptr) noexcept;",
-        instance, inner,
+        "{} *cxxbridge1$box${}$alloc() noexcept;",
+        inner, instance,
     );
     writeln!(
         out,
@@ -1415,8 +1415,8 @@
     let instance = ident.to_symbol();
 
     writeln!(out, "template <>");
-    writeln!(out, "void Box<{}>::uninit() noexcept {{", inner);
-    writeln!(out, "  cxxbridge1$box${}$uninit(this);", instance);
+    writeln!(out, "{} *Box<{}>::alloc() noexcept {{", inner, inner);
+    writeln!(out, "  return cxxbridge1$box${}$alloc();", instance);
     writeln!(out, "}}");
 
     writeln!(out, "template <>");
diff --git a/include/cxx.h b/include/cxx.h
index 8a91f26..9ba49a1 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -200,6 +200,7 @@
       typename std::add_pointer<typename std::add_const<T>::type>::type;
   using pointer = typename std::add_pointer<T>::type;
 
+  Box() = delete;
   Box(const Box &);
   Box(Box &&) noexcept;
   ~Box() noexcept;
@@ -225,8 +226,9 @@
   T *into_raw() noexcept;
 
 private:
-  Box() noexcept;
-  void uninit() noexcept;
+  class uninit;
+  Box(uninit) noexcept;
+  static T *alloc() noexcept;
   void drop() noexcept;
   T *ptr;
 };
@@ -546,6 +548,9 @@
 #ifndef CXXBRIDGE1_RUST_BOX
 #define CXXBRIDGE1_RUST_BOX
 template <typename T>
+class Box<T>::uninit {};
+
+template <typename T>
 Box<T>::Box(const Box &other) : Box(*other) {}
 
 template <typename T>
@@ -554,14 +559,12 @@
 }
 
 template <typename T>
-Box<T>::Box(const T &val) {
-  this->uninit();
+Box<T>::Box(const T &val) : ptr(alloc()) {
   ::new (this->ptr) T(val);
 }
 
 template <typename T>
-Box<T>::Box(T &&val) {
-  this->uninit();
+Box<T>::Box(T &&val) : ptr(alloc()) {
   ::new (this->ptr) T(std::move(val));
 }
 
@@ -578,7 +581,7 @@
     if (this->ptr) {
       **this = *other;
     } else {
-      this->uninit();
+      this->ptr = alloc();
       ::new (this->ptr) T(*other);
     }
   }
@@ -618,15 +621,15 @@
 template <typename T>
 template <typename... Fields>
 Box<T> Box<T>::in_place(Fields &&... fields) {
-  Box box;
-  box.uninit();
+  Box box = uninit{};
+  box.ptr = alloc();
   ::new (box.ptr) T{std::forward<Fields>(fields)...};
   return box;
 }
 
 template <typename T>
 Box<T> Box<T>::from_raw(T *raw) noexcept {
-  Box box;
+  Box box = uninit{};
   box.ptr = raw;
   return box;
 }
@@ -639,7 +642,7 @@
 }
 
 template <typename T>
-Box<T>::Box() noexcept = default;
+Box<T>::Box(uninit) noexcept {}
 #endif // CXXBRIDGE1_RUST_BOX
 
 #ifndef CXXBRIDGE1_RUST_VEC
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 2730b20..4a17161 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -951,11 +951,11 @@
 
 fn expand_rust_box(ident: &RustName, types: &Types) -> TokenStream {
     let link_prefix = format!("cxxbridge1$box${}$", types.resolve(ident).to_symbol());
-    let link_uninit = format!("{}uninit", link_prefix);
+    let link_alloc = format!("{}alloc", link_prefix);
     let link_drop = format!("{}drop", link_prefix);
 
     let local_prefix = format_ident!("{}__box_", &ident.rust);
-    let local_uninit = format_ident!("{}uninit", local_prefix);
+    let local_alloc = format_ident!("{}alloc", local_prefix);
     let local_drop = format_ident!("{}drop", local_prefix);
 
     let span = ident.span();
@@ -963,14 +963,9 @@
         #[doc(hidden)]
         unsafe impl ::cxx::private::ImplBox for #ident {}
         #[doc(hidden)]
-        #[export_name = #link_uninit]
-        unsafe extern "C" fn #local_uninit(
-            this: *mut ::std::boxed::Box<::std::mem::MaybeUninit<#ident>>,
-        ) {
-            ::std::ptr::write(
-                this,
-                ::std::boxed::Box::new(::std::mem::MaybeUninit::uninit()),
-            );
+        #[export_name = #link_alloc]
+        unsafe extern "C" fn #local_alloc() -> *mut ::std::mem::MaybeUninit<#ident> {
+            ::std::boxed::Box::into_raw(::std::boxed::Box::new(::std::mem::MaybeUninit::uninit()))
         }
         #[doc(hidden)]
         #[export_name = #link_drop]