diff --git a/Resample/FFCompute/ComputeBA.cpp b/Resample/FFCompute/ComputeBA.cpp
index d6ed1937be229c8007ce71da4e31fbc15fb0d192..3f88977f07cff20eb305cc532c19d41cd3d75a37 100644
--- a/Resample/FFCompute/ComputeBA.cpp
+++ b/Resample/FFCompute/ComputeBA.cpp
@@ -17,15 +17,11 @@
 #include "Resample/Element/DiffuseElement.h"
 #include "Sample/Scattering/IFormFactor.h"
 
-ComputeBA::ComputeBA(const IFormFactor& ff, size_t i_layer) : IComputeScalar(ff, i_layer) {}
+ComputeBA::ComputeBA(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer)
+    : IComputeScalar(std::move(ff), i_layer) {}
 
 ComputeBA::~ComputeBA() = default;
 
-ComputeBA* ComputeBA::clone() const
-{
-    return new ComputeBA(*m_ff, m_i_layer);
-}
-
 complex_t ComputeBA::coherentFF(const DiffuseElement& ele) const
 {
     const WavevectorInfo& wavevectors = ele.wavevectorInfo();
diff --git a/Resample/FFCompute/ComputeBA.h b/Resample/FFCompute/ComputeBA.h
index 697beec393ca2e2a8e779a6d25f3ac169f30f6d3..619a5a366d617422b874d0dbe9473c025a75ecc6 100644
--- a/Resample/FFCompute/ComputeBA.h
+++ b/Resample/FFCompute/ComputeBA.h
@@ -27,11 +27,9 @@
 
 class ComputeBA : public IComputeScalar {
 public:
-    ComputeBA(const IFormFactor& ff, size_t i_layer);
+    ComputeBA(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer);
     ~ComputeBA() override;
 
-    ComputeBA* clone() const override;
-
     //! Calculates and returns a form factor calculation in BA
     complex_t coherentFF(const DiffuseElement& ele) const override;
 };
diff --git a/Resample/FFCompute/ComputeBAPol.cpp b/Resample/FFCompute/ComputeBAPol.cpp
index f165593d09e0329ce0645a97fdbe31443b561e93..b5e40d1bf8d20d98499718fb2c1b4b6ccf7bc138 100644
--- a/Resample/FFCompute/ComputeBAPol.cpp
+++ b/Resample/FFCompute/ComputeBAPol.cpp
@@ -17,15 +17,11 @@
 #include "Resample/Element/DiffuseElement.h"
 #include "Sample/Scattering/IFormFactor.h"
 
-ComputeBAPol::ComputeBAPol(const IFormFactor& ff, size_t i_layer) : IComputePol(ff, i_layer) {}
+ComputeBAPol::ComputeBAPol(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer)
+    : IComputePol(std::move(ff), i_layer) {}
 
 ComputeBAPol::~ComputeBAPol() = default;
 
-ComputeBAPol* ComputeBAPol::clone() const
-{
-    return new ComputeBAPol(*m_ff, m_i_layer);
-}
-
 Eigen::Matrix2cd ComputeBAPol::coherentPolFF(const DiffuseElement& ele) const
 {
     Eigen::Matrix2cd ff_BA = m_ff->thePolFF(ele.wavevectorInfo());
diff --git a/Resample/FFCompute/ComputeBAPol.h b/Resample/FFCompute/ComputeBAPol.h
index 16592303333987548a29adf2102fde2d594bcea0..0c79bd93ce288dd5dfb8ca0429a49c4dadc8d8c6 100644
--- a/Resample/FFCompute/ComputeBAPol.h
+++ b/Resample/FFCompute/ComputeBAPol.h
@@ -27,11 +27,9 @@
 
 class ComputeBAPol : public IComputePol {
 public:
-    ComputeBAPol(const IFormFactor& ff, size_t i_layer);
+    ComputeBAPol(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer);
     ~ComputeBAPol() override;
 
-    ComputeBAPol* clone() const override;
-
     //! Calculates and returns a polarized form factor calculation in BA
     Eigen::Matrix2cd coherentPolFF(const DiffuseElement& ele) const override;
 };
diff --git a/Resample/FFCompute/ComputeDWBA.cpp b/Resample/FFCompute/ComputeDWBA.cpp
index cfabcffb6b9633b97be105a8f8b5fc883443f0b2..24450f16bc56581952648492d197f0e45ae35c29 100644
--- a/Resample/FFCompute/ComputeDWBA.cpp
+++ b/Resample/FFCompute/ComputeDWBA.cpp
@@ -19,15 +19,11 @@
 #include "Resample/Flux/ScalarFlux.h"
 #include "Sample/Scattering/IFormFactor.h"
 
-ComputeDWBA::ComputeDWBA(const IFormFactor& ff, size_t i_layer) : IComputeScalar(ff, i_layer) {}
+ComputeDWBA::ComputeDWBA(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer)
+    : IComputeScalar(std::move(ff), i_layer) {}
 
 ComputeDWBA::~ComputeDWBA() = default;
 
-ComputeDWBA* ComputeDWBA::clone() const
-{
-    return new ComputeDWBA(*m_ff, m_i_layer);
-}
-
 complex_t ComputeDWBA::coherentFF(const DiffuseElement& ele) const
 {
     const WavevectorInfo& wavevectors = ele.wavevectorInfo();
diff --git a/Resample/FFCompute/ComputeDWBA.h b/Resample/FFCompute/ComputeDWBA.h
index 7c664ece4f51be29e582494f5f6b1dbb4144df7a..45f9ad45e20f30dfe45c0ad6bbf04ca03b2317a9 100644
--- a/Resample/FFCompute/ComputeDWBA.h
+++ b/Resample/FFCompute/ComputeDWBA.h
@@ -29,11 +29,9 @@ class IFlux;
 
 class ComputeDWBA : public IComputeScalar {
 public:
-    ComputeDWBA(const IFormFactor& ff, size_t i_layer);
+    ComputeDWBA(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer);
     ~ComputeDWBA() override;
 
-    ComputeDWBA* clone() const override;
-
     //! Returns the coherent sum of the four DWBA terms for scalar scattering.
     complex_t coherentFF(const DiffuseElement& ele) const override;
 
diff --git a/Resample/FFCompute/ComputeDWBAPol.cpp b/Resample/FFCompute/ComputeDWBAPol.cpp
index 439d457c733282871daf267ebf488213d968bc72..1c27fd50f7309bf8860a3f59d066f5ee43db1d3c 100644
--- a/Resample/FFCompute/ComputeDWBAPol.cpp
+++ b/Resample/FFCompute/ComputeDWBAPol.cpp
@@ -30,15 +30,11 @@ complex_t VecMatVecProduct(const Eigen::Vector2cd& vec1, const Eigen::Matrix2cd&
 } // namespace
 
 
-ComputeDWBAPol::ComputeDWBAPol(const IFormFactor& ff, size_t i_layer) : IComputePol(ff, i_layer) {}
+ComputeDWBAPol::ComputeDWBAPol(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer)
+    : IComputePol(std::move(ff), i_layer) {}
 
 ComputeDWBAPol::~ComputeDWBAPol() = default;
 
-ComputeDWBAPol* ComputeDWBAPol::clone() const
-{
-    return new ComputeDWBAPol(*m_ff, m_i_layer);
-}
-
 Eigen::Matrix2cd ComputeDWBAPol::coherentPolFF(const DiffuseElement& ele) const
 {
     const WavevectorInfo& wavevectors = ele.wavevectorInfo();
diff --git a/Resample/FFCompute/ComputeDWBAPol.h b/Resample/FFCompute/ComputeDWBAPol.h
index 2e6263c88a8f233f8762548e708f219d2bb6d33e..ecb7dce059de4dc2d9cde88dfba67e81e66103fb 100644
--- a/Resample/FFCompute/ComputeDWBAPol.h
+++ b/Resample/FFCompute/ComputeDWBAPol.h
@@ -27,11 +27,9 @@
 
 class ComputeDWBAPol : public IComputePol {
 public:
-    ComputeDWBAPol(const IFormFactor& ff, size_t i_layer);
+    ComputeDWBAPol(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer);
     ~ComputeDWBAPol() override;
 
-    ComputeDWBAPol* clone() const override;
-
     //! Returns the coherent sum of the four DWBA terms for polarized scattering.
     Eigen::Matrix2cd coherentPolFF(const DiffuseElement& ele) const override;
 
diff --git a/Resample/FFCompute/IComputeFF.cpp b/Resample/FFCompute/IComputeFF.cpp
index f3de4063ea4bba95c7e3d390ac4381cb94afaf6d..f7a617bab9666d246e2f238872e9bb03bc67ef70 100644
--- a/Resample/FFCompute/IComputeFF.cpp
+++ b/Resample/FFCompute/IComputeFF.cpp
@@ -15,7 +15,8 @@
 #include "Resample/FFCompute/IComputeFF.h"
 #include "Sample/Scattering/IFormFactor.h"
 
-IComputeFF::IComputeFF(const IFormFactor& ff, size_t i_layer) : m_ff(ff.clone()), m_i_layer(i_layer)
+IComputeFF::IComputeFF(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer)
+    : m_ff(std::move(ff)), m_i_layer(i_layer)
 {
 }
 
diff --git a/Resample/FFCompute/IComputeFF.h b/Resample/FFCompute/IComputeFF.h
index 3b6237df01c4240e953b78dbf106443447e589f3..9be8723aeabb40a19a0ddcc0452e91b3983d26c2 100644
--- a/Resample/FFCompute/IComputeFF.h
+++ b/Resample/FFCompute/IComputeFF.h
@@ -35,7 +35,6 @@ class WavevectorInfo; // used by all children
 class IComputeFF {
 public:
     virtual ~IComputeFF();
-    virtual IComputeFF* clone() const = 0;
 
     size_t iLayer() const { return m_i_layer; }
 
@@ -44,7 +43,7 @@ public:
     double topZ(const IRotation& rotation) const;
 
 protected:
-    IComputeFF(const IFormFactor& ff, size_t i_layer);
+    IComputeFF(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer);
 
     const std::unique_ptr<const IFormFactor> m_ff;
     const size_t m_i_layer;
diff --git a/Resample/FFCompute/IComputePol.h b/Resample/FFCompute/IComputePol.h
index c413dcb56ba51af390de6a18c886f7a6b3ad6ba9..313ee9ec922ec283d4065e57298962da62d3bcce 100644
--- a/Resample/FFCompute/IComputePol.h
+++ b/Resample/FFCompute/IComputePol.h
@@ -32,7 +32,8 @@ public:
     virtual Eigen::Matrix2cd coherentPolFF(const DiffuseElement& ele) const = 0;
 
 protected:
-    IComputePol(const IFormFactor& ff, size_t i_layer) : IComputeFF(ff, i_layer) {}
+    IComputePol(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer)
+        : IComputeFF(std::move(ff), i_layer) {}
 };
 
 #endif // BORNAGAIN_RESAMPLE_FFCOMPUTE_ICOMPUTEPOL_H
diff --git a/Resample/FFCompute/IComputeScalar.h b/Resample/FFCompute/IComputeScalar.h
index 4618f9145ddc8d441ccfa314890b89e41ecba190..2036bba79d223c5f9415bdb639d52eaa918d8f6b 100644
--- a/Resample/FFCompute/IComputeScalar.h
+++ b/Resample/FFCompute/IComputeScalar.h
@@ -34,7 +34,8 @@ public:
     virtual complex_t coherentFF(const DiffuseElement& sim_element) const = 0;
 
 protected:
-    IComputeScalar(const IFormFactor& ff, size_t i_layer) : IComputeFF(ff, i_layer) {}
+    IComputeScalar(std::unique_ptr<const IFormFactor>&& ff, size_t i_layer)
+        : IComputeFF(std::move(ff), i_layer) {}
 };
 
 #endif // BORNAGAIN_RESAMPLE_FFCOMPUTE_ICOMPUTESCALAR_H
diff --git a/Resample/Processed/ProcessedLayout.cpp b/Resample/Processed/ProcessedLayout.cpp
index 8792da45c58050d91bcb42e038da68fe1ffc3173..207deb4ae894fc256dea33a960f119b12ad46df5 100644
--- a/Resample/Processed/ProcessedLayout.cpp
+++ b/Resample/Processed/ProcessedLayout.cpp
@@ -192,21 +192,21 @@ CoherentFFSum ProcessedLayout::processParticle(const IParticle& particle, const
         const auto& pair = tmp_ff_list.at(i);
         const size_t i_layer = pair.second;
         const Material& material = slices[i_layer].material();
-        const std::unique_ptr<IFormFactor> ff(pair.first->clone());
+        std::unique_ptr<IFormFactor> ff(pair.first->clone());
         ff->setAmbientMaterial(material);
 
         std::unique_ptr<IComputeFF> computer;
         if (slices.size() > 1) {
             if (m_polarized)
-                computer = std::make_unique<ComputeDWBAPol>(*ff, i_layer);
+                computer = std::make_unique<ComputeDWBAPol>(std::move(ff), i_layer);
             else
-                computer = std::make_unique<ComputeDWBA>(*ff, i_layer);
+                computer = std::make_unique<ComputeDWBA>(std::move(ff), i_layer);
         } else {
             // no need for DWBA, use BA
             if (m_polarized)
-                computer = std::make_unique<ComputeBAPol>(*ff, i_layer);
+                computer = std::make_unique<ComputeBAPol>(std::move(ff), i_layer);
             else
-                computer = std::make_unique<ComputeBA>(*ff, i_layer);
+                computer = std::make_unique<ComputeBA>(std::move(ff), i_layer);
         }
         terms.emplace_back(computer.release());
     }
diff --git a/Tests/UnitTests/Core/Sample/FormFactorCoherentSumTest.cpp b/Tests/UnitTests/Core/Sample/FormFactorCoherentSumTest.cpp
index f23e580023ae3f73a6d213c4a8344b65eee83a1d..98cd4b98b987f00d40221313b9a9551e05ba224a 100644
--- a/Tests/UnitTests/Core/Sample/FormFactorCoherentSumTest.cpp
+++ b/Tests/UnitTests/Core/Sample/FormFactorCoherentSumTest.cpp
@@ -8,8 +8,8 @@ class CoherentFFSumTest : public ::testing::Test {
 
 TEST_F(CoherentFFSumTest, RelAbundance)
 {
-    FormFactorFullSphere ff(5.0);
-    std::shared_ptr<const IComputeFF> part(new ComputeBA(ff, 0));
+    auto ff = std::make_unique<FormFactorFullSphere>(5.0);
+    std::shared_ptr<const IComputeFF> part(new ComputeBA(std::move(ff), 0));
     CoherentFFSum ffw(1.0, {part});
     EXPECT_EQ(1.0, ffw.relativeAbundance());
     EXPECT_EQ(5.0, ffw.radialExtension());