Drop trivial special members

Do not define trivial constructors or destructors unless necessary
(e.g., for implementing pimpl) following the rule of zero. Define
virtual base class destructors out-of-line to avoid emitting vtables in
every translation unit.

Change-Id: Iea2d8978e62a8ee5a97b86cbb4e858d56e0fb274
diff --git a/include/ceres/autodiff_first_order_function.h b/include/ceres/autodiff_first_order_function.h
index fa63785..4ace559 100644
--- a/include/ceres/autodiff_first_order_function.h
+++ b/include/ceres/autodiff_first_order_function.h
@@ -110,7 +110,6 @@
     static_assert(kNumParameters > 0, "kNumParameters must be positive");
   }
 
-  ~AutoDiffFirstOrderFunction() override = default;
 
   bool Evaluate(const double* const parameters,
                 double* cost,
diff --git a/include/ceres/autodiff_local_parameterization.h b/include/ceres/autodiff_local_parameterization.h
index aadee81..76e22ed 100644
--- a/include/ceres/autodiff_local_parameterization.h
+++ b/include/ceres/autodiff_local_parameterization.h
@@ -114,7 +114,6 @@
   explicit AutoDiffLocalParameterization(Functor* functor)
       : functor_(functor) {}
 
-  ~AutoDiffLocalParameterization() override = default;
   bool Plus(const double* x,
             const double* delta,
             double* x_plus_delta) const override {
diff --git a/include/ceres/autodiff_manifold.h b/include/ceres/autodiff_manifold.h
index fa326ac..462fcde 100644
--- a/include/ceres/autodiff_manifold.h
+++ b/include/ceres/autodiff_manifold.h
@@ -152,7 +152,6 @@
   // Takes ownership of functor.
   explicit AutoDiffManifold(Functor* functor) : functor_(functor) {}
 
-  ~AutoDiffManifold() override = default;
 
   int AmbientSize() const override { return kAmbientSize; }
   int TangentSize() const override { return kTangentSize; }
diff --git a/include/ceres/context.h b/include/ceres/context.h
index e22df7e..ab42bfe 100644
--- a/include/ceres/context.h
+++ b/include/ceres/context.h
@@ -31,6 +31,8 @@
 #ifndef CERES_PUBLIC_CONTEXT_H_
 #define CERES_PUBLIC_CONTEXT_H_
 
+#include "ceres/internal/port.h"
+
 namespace ceres {
 
 // A global context for processing data in Ceres.  This provides a mechanism to
@@ -39,13 +41,13 @@
 // Problems, either serially or in parallel. When using it with multiple
 // Problems at the same time, they may end up contending for resources
 // (e.g. threads) managed by the Context.
-class Context {
+class CERES_EXPORT_INTERNAL Context {
  public:
-  Context() = default;
+  Context();
   Context(const Context&) = delete;
   void operator=(const Context&) = delete;
 
-  virtual ~Context() = default;
+  virtual ~Context();
 
   // Creates a context object and the caller takes ownership.
   static Context* Create();
diff --git a/include/ceres/cost_function.h b/include/ceres/cost_function.h
index 7e0f2cc..a904a2b 100644
--- a/include/ceres/cost_function.h
+++ b/include/ceres/cost_function.h
@@ -63,11 +63,11 @@
 // when added with AddResidualBlock().
 class CERES_EXPORT CostFunction {
  public:
-  CostFunction() : num_residuals_(0) {}
+  CostFunction();
   CostFunction(const CostFunction&) = delete;
   void operator=(const CostFunction&) = delete;
 
-  virtual ~CostFunction() = default;
+  virtual ~CostFunction();
 
   // Inputs:
   //
diff --git a/include/ceres/dynamic_cost_function.h b/include/ceres/dynamic_cost_function.h
index 4d0c2bc..069ad59 100644
--- a/include/ceres/dynamic_cost_function.h
+++ b/include/ceres/dynamic_cost_function.h
@@ -40,7 +40,6 @@
 // parameter blocks and set the number of residuals at run time.
 class CERES_EXPORT DynamicCostFunction : public CostFunction {
  public:
-  ~DynamicCostFunction() override = default;
 
   virtual void AddParameterBlock(int size) {
     mutable_parameter_block_sizes()->push_back(size);
diff --git a/include/ceres/evaluation_callback.h b/include/ceres/evaluation_callback.h
index 2ff7c47..b7c52cf 100644
--- a/include/ceres/evaluation_callback.h
+++ b/include/ceres/evaluation_callback.h
@@ -62,7 +62,7 @@
 // execute faster.
 class CERES_EXPORT EvaluationCallback {
  public:
-  virtual ~EvaluationCallback() = default;
+  virtual ~EvaluationCallback();
 
   // Called before Ceres requests residuals or jacobians for a given setting of
   // the parameters. User parameters (the double* values provided to the cost
diff --git a/include/ceres/first_order_function.h b/include/ceres/first_order_function.h
index eb66c5a..7b92cd0 100644
--- a/include/ceres/first_order_function.h
+++ b/include/ceres/first_order_function.h
@@ -39,7 +39,7 @@
 // and its gradient.
 class CERES_EXPORT FirstOrderFunction {
  public:
-  virtual ~FirstOrderFunction() = default;
+  virtual ~FirstOrderFunction();
 
   // cost is never null. gradient may be null. The return value
   // indicates whether the evaluation was successful or not.
diff --git a/include/ceres/iteration_callback.h b/include/ceres/iteration_callback.h
index d52d466..488c015 100644
--- a/include/ceres/iteration_callback.h
+++ b/include/ceres/iteration_callback.h
@@ -164,8 +164,6 @@
 //     explicit LoggingCallback(bool log_to_stdout)
 //         : log_to_stdout_(log_to_stdout) {}
 //
-//     ~LoggingCallback() {}
-//
 //     CallbackReturnType operator()(const IterationSummary& summary) {
 //       const char* kReportRowFormat =
 //           "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e "
@@ -194,7 +192,7 @@
 //
 class CERES_EXPORT IterationCallback {
  public:
-  virtual ~IterationCallback() = default;
+  virtual ~IterationCallback();
   virtual CallbackReturnType operator()(const IterationSummary& summary) = 0;
 };
 
diff --git a/include/ceres/local_parameterization.h b/include/ceres/local_parameterization.h
index b92ec9b..b16c893 100644
--- a/include/ceres/local_parameterization.h
+++ b/include/ceres/local_parameterization.h
@@ -155,7 +155,6 @@
 class CERES_EXPORT IdentityParameterization : public LocalParameterization {
  public:
   explicit IdentityParameterization(int size);
-  ~IdentityParameterization() override = default;
   bool Plus(const double* x,
             const double* delta,
             double* x_plus_delta) const override;
@@ -176,7 +175,6 @@
  public:
   explicit SubsetParameterization(int size,
                                   const std::vector<int>& constant_parameters);
-  ~SubsetParameterization() override = default;
   bool Plus(const double* x,
             const double* delta,
             double* x_plus_delta) const override;
@@ -201,7 +199,6 @@
 // theta) part.
 class CERES_EXPORT QuaternionParameterization : public LocalParameterization {
  public:
-  ~QuaternionParameterization() override = default;
   bool Plus(const double* x,
             const double* delta,
             double* x_plus_delta) const override;
@@ -224,7 +221,6 @@
 class CERES_EXPORT EigenQuaternionParameterization
     : public ceres::LocalParameterization {
  public:
-  ~EigenQuaternionParameterization() override = default;
   bool Plus(const double* x,
             const double* delta,
             double* x_plus_delta) const override;
@@ -250,7 +246,6 @@
     : public LocalParameterization {
  public:
   explicit HomogeneousVectorParameterization(int size);
-  ~HomogeneousVectorParameterization() override = default;
   bool Plus(const double* x,
             const double* delta,
             double* x_plus_delta) const override;
@@ -306,7 +301,6 @@
  public:
   ProductParameterization(const ProductParameterization&) = delete;
   ProductParameterization& operator=(const ProductParameterization&) = delete;
-  ~ProductParameterization() override = default;
   //
   // NOTE: The constructor takes ownership of the input local
   // parameterizations.
diff --git a/include/ceres/loss_function.h b/include/ceres/loss_function.h
index 4da78bf..bc9d6a1 100644
--- a/include/ceres/loss_function.h
+++ b/include/ceres/loss_function.h
@@ -85,7 +85,7 @@
 
 class CERES_EXPORT LossFunction {
  public:
-  virtual ~LossFunction() = default;
+  virtual ~LossFunction();
 
   // For a residual vector with squared 2-norm 'sq_norm', this method
   // is required to fill in the value and derivatives of the loss
diff --git a/include/ceres/manifold.h b/include/ceres/manifold.h
index da56500..178d01b 100644
--- a/include/ceres/manifold.h
+++ b/include/ceres/manifold.h
@@ -148,7 +148,7 @@
 
 class CERES_EXPORT Manifold {
  public:
-  virtual ~Manifold() = default;
+  virtual ~Manifold();
 
   // Dimension of the ambient space in which the manifold is embedded.
   virtual int AmbientSize() const = 0;
@@ -231,7 +231,6 @@
 class CERES_EXPORT EuclideanManifold : public Manifold {
  public:
   EuclideanManifold(int size);
-  ~EuclideanManifold() override = default;
   int AmbientSize() const override;
   int TangentSize() const override;
   bool Plus(const double* x,
@@ -255,7 +254,6 @@
 class CERES_EXPORT SubsetManifold : public Manifold {
  public:
   SubsetManifold(int size, const std::vector<int>& constant_parameters);
-  ~SubsetManifold() override = default;
   int AmbientSize() const override;
   int TangentSize() const override;
 
@@ -293,7 +291,6 @@
  public:
   ProductManifold(const ProductManifold&) = delete;
   ProductManifold& operator=(const ProductManifold&) = delete;
-  ~ProductManifold() override = default;
 
   // NOTE: The constructor takes ownership of the input
   // manifolds.
@@ -368,8 +365,6 @@
 // and to_delta( [q0; u_{3x1}] ) = u / |u| * atan2(|u|, q0)
 class CERES_EXPORT QuaternionManifold : public Manifold {
  public:
-  QuaternionManifold() = default;
-  ~QuaternionManifold() override = default;
   int AmbientSize() const override { return 4; }
   int TangentSize() const override { return 3; }
 
@@ -394,8 +389,6 @@
 // difference is important and requires a different manifold.
 class CERES_EXPORT EigenQuaternionManifold : public Manifold {
  public:
-  EigenQuaternionManifold() = default;
-  ~EigenQuaternionManifold() override = default;
   int AmbientSize() const override { return 4; }
   int TangentSize() const override { return 3; }
 
diff --git a/include/ceres/sized_cost_function.h b/include/ceres/sized_cost_function.h
index b8a6a8c..ad99002 100644
--- a/include/ceres/sized_cost_function.h
+++ b/include/ceres/sized_cost_function.h
@@ -61,7 +61,6 @@
     *mutable_parameter_block_sizes() = std::vector<int32_t>{Ns...};
   }
 
-  ~SizedCostFunction() override = default;
 
   // Subclasses must implement Evaluate().
 };
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 7a8bd41..cfb1b90 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -57,9 +57,9 @@
     block_sparse_matrix.cc
     block_structure.cc
     c_api.cc
+    callbacks.cc
     canonical_views_clustering.cc
     cgnr_solver.cc
-    callbacks.cc
     compressed_col_sparse_matrix_utils.cc
     compressed_row_jacobian_writer.cc
     compressed_row_sparse_matrix.cc
@@ -69,6 +69,7 @@
     context_impl.cc
     coordinate_descent_minimizer.cc
     corrector.cc
+    cost_function.cc
     covariance.cc
     covariance_impl.cc
     cxsparse.cc
@@ -82,11 +83,13 @@
     dynamic_compressed_row_jacobian_writer.cc
     dynamic_compressed_row_sparse_matrix.cc
     dynamic_sparse_normal_cholesky_solver.cc
-    evaluator.cc
     eigensparse.cc
+    evaluation_callback.cc
+    evaluator.cc
     file.cc
-    float_suitesparse.cc
+    first_order_function.cc
     float_cxsparse.cc
+    float_suitesparse.cc
     function_sample.cc
     gradient_checker.cc
     gradient_checking_cost_function.cc
@@ -95,6 +98,7 @@
     implicit_schur_complement.cc
     inner_product_computer.cc
     is_close.cc
+    iteration_callback.cc
     iterative_refiner.cc
     iterative_schur_complement_solver.cc
     levenberg_marquardt_strategy.cc
@@ -131,16 +135,16 @@
     single_linkage_clustering.cc
     solver.cc
     solver_utils.cc
-    sparse_matrix.cc
     sparse_cholesky.cc
+    sparse_matrix.cc
     sparse_normal_cholesky_solver.cc
-    subset_preconditioner.cc
     stringprintf.cc
+    subset_preconditioner.cc
     suitesparse.cc
     thread_token_provider.cc
     triplet_sparse_matrix.cc
-    trust_region_preprocessor.cc
     trust_region_minimizer.cc
+    trust_region_preprocessor.cc
     trust_region_step_evaluator.cc
     trust_region_strategy.cc
     types.cc
diff --git a/internal/ceres/autodiff_benchmarks/brdf_cost_function.h b/internal/ceres/autodiff_benchmarks/brdf_cost_function.h
index 715d8b0..767b423 100644
--- a/internal/ceres/autodiff_benchmarks/brdf_cost_function.h
+++ b/internal/ceres/autodiff_benchmarks/brdf_cost_function.h
@@ -45,7 +45,6 @@
 // https://github.com/wdas/brdf/blob/master/src/brdfs/disney.brdf
 struct Brdf {
  public:
-  Brdf() = default;
 
   template <typename T>
   inline bool operator()(const T* const material,
diff --git a/internal/ceres/autodiff_benchmarks/snavely_reprojection_error.h b/internal/ceres/autodiff_benchmarks/snavely_reprojection_error.h
index 795342f..439ee9b 100644
--- a/internal/ceres/autodiff_benchmarks/snavely_reprojection_error.h
+++ b/internal/ceres/autodiff_benchmarks/snavely_reprojection_error.h
@@ -40,7 +40,6 @@
   SnavelyReprojectionError(double observed_x, double observed_y)
       : observed_x(observed_x), observed_y(observed_y) {}
 
-  SnavelyReprojectionError() = default;
   template <typename T>
   inline bool operator()(const T* const camera,
                          const T* const point,
diff --git a/internal/ceres/block_sparse_matrix.cc b/internal/ceres/block_sparse_matrix.cc
index e06bd2f..9359354 100644
--- a/internal/ceres/block_sparse_matrix.cc
+++ b/internal/ceres/block_sparse_matrix.cc
@@ -46,8 +46,6 @@
 
 using std::vector;
 
-BlockSparseMatrix::~BlockSparseMatrix() = default;
-
 BlockSparseMatrix::BlockSparseMatrix(
     CompressedRowBlockStructure* block_structure)
     : num_rows_(0),
diff --git a/internal/ceres/block_sparse_matrix.h b/internal/ceres/block_sparse_matrix.h
index 0707546..448282c 100644
--- a/internal/ceres/block_sparse_matrix.h
+++ b/internal/ceres/block_sparse_matrix.h
@@ -68,8 +68,6 @@
   BlockSparseMatrix(const BlockSparseMatrix&) = delete;
   void operator=(const BlockSparseMatrix&) = delete;
 
-  ~BlockSparseMatrix() override;
-
   // Implementation of SparseMatrix interface.
   void SetZero() final;
   void RightMultiply(const double* x, double* y) const final;
diff --git a/internal/ceres/canonical_views_clustering.cc b/internal/ceres/canonical_views_clustering.cc
index 51cd4cb..0dd77a0 100644
--- a/internal/ceres/canonical_views_clustering.cc
+++ b/internal/ceres/canonical_views_clustering.cc
@@ -48,7 +48,6 @@
 
 class CanonicalViewsClustering {
  public:
-  CanonicalViewsClustering() = default;
 
   // Compute the canonical views clustering of the vertices of the
   // graph. centers will contain the vertices that are the identified
diff --git a/internal/ceres/cgnr_linear_operator.h b/internal/ceres/cgnr_linear_operator.h
index 569ecdc..995e531 100644
--- a/internal/ceres/cgnr_linear_operator.h
+++ b/internal/ceres/cgnr_linear_operator.h
@@ -82,7 +82,6 @@
  public:
   CgnrLinearOperator(const LinearOperator& A, const double* D)
       : A_(A), D_(D), z_(new double[A.num_rows()]) {}
-  ~CgnrLinearOperator() override = default;
 
   void RightMultiply(const double* x, double* y) const final {
     std::fill(z_.get(), z_.get() + A_.num_rows(), 0.0);
diff --git a/internal/ceres/compressed_row_sparse_matrix.h b/internal/ceres/compressed_row_sparse_matrix.h
index 0805ee7..c1766b7 100644
--- a/internal/ceres/compressed_row_sparse_matrix.h
+++ b/internal/ceres/compressed_row_sparse_matrix.h
@@ -31,6 +31,7 @@
 #ifndef CERES_INTERNAL_COMPRESSED_ROW_SPARSE_MATRIX_H_
 #define CERES_INTERNAL_COMPRESSED_ROW_SPARSE_MATRIX_H_
 
+#include <memory>
 #include <vector>
 
 #include "ceres/internal/port.h"
diff --git a/internal/ceres/context.cc b/internal/ceres/context.cc
index 55e7635..fde16b8 100644
--- a/internal/ceres/context.cc
+++ b/internal/ceres/context.cc
@@ -34,6 +34,8 @@
 
 namespace ceres {
 
+Context::Context() = default;
 Context* Context::Create() { return new internal::ContextImpl(); }
+Context::~Context() = default;
 
 }  // namespace ceres
diff --git a/internal/ceres/context_impl.cc b/internal/ceres/context_impl.cc
index 20fe5cb..1acf724 100644
--- a/internal/ceres/context_impl.cc
+++ b/internal/ceres/context_impl.cc
@@ -33,6 +33,8 @@
 namespace ceres {
 namespace internal {
 
+ContextImpl::ContextImpl() = default;
+
 void ContextImpl::EnsureMinimumThreads(int num_threads) {
 #ifdef CERES_USE_CXX_THREADS
   thread_pool.Resize(num_threads);
diff --git a/internal/ceres/context_impl.h b/internal/ceres/context_impl.h
index f94d559..2f9f74a 100644
--- a/internal/ceres/context_impl.h
+++ b/internal/ceres/context_impl.h
@@ -47,11 +47,10 @@
 
 class CERES_EXPORT_INTERNAL ContextImpl : public Context {
  public:
-  ContextImpl() = default;
+  ContextImpl();
   ContextImpl(const ContextImpl&) = delete;
   void operator=(const ContextImpl&) = delete;
 
-  ~ContextImpl() override = default;
 
   // When compiled with C++ threading support, resize the thread pool to have
   // at min(num_thread, num_hardware_threads) where num_hardware_threads is
diff --git a/internal/ceres/cost_function.cc b/internal/ceres/cost_function.cc
new file mode 100644
index 0000000..7597b43
--- /dev/null
+++ b/internal/ceres/cost_function.cc
@@ -0,0 +1,39 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2022 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+//         keir@google.m (Keir Mierle)
+
+#include "ceres/cost_function.h"
+
+namespace ceres {
+
+CostFunction::CostFunction() : num_residuals_(0) {}
+CostFunction::~CostFunction() = default;
+
+}  // namespace ceres
diff --git a/internal/ceres/covariance_test.cc b/internal/ceres/covariance_test.cc
index b117a64..20b480f 100644
--- a/internal/ceres/covariance_test.cc
+++ b/internal/ceres/covariance_test.cc
@@ -379,7 +379,6 @@
 // x_plus_delta = delta * x;
 class PolynomialParameterization : public LocalParameterization {
  public:
-  ~PolynomialParameterization() final = default;
 
   bool Plus(const double* x,
             const double* delta,
@@ -402,7 +401,6 @@
 // x_plus_delta = delta * x;
 class PolynomialManifold : public Manifold {
  public:
-  ~PolynomialManifold() final = default;
 
   bool Plus(const double* x,
             const double* delta,
diff --git a/internal/ceres/dense_cholesky.cc b/internal/ceres/dense_cholesky.cc
index 841ceb1..af555e7 100644
--- a/internal/ceres/dense_cholesky.cc
+++ b/internal/ceres/dense_cholesky.cc
@@ -59,6 +59,8 @@
 namespace ceres {
 namespace internal {
 
+DenseCholesky::~DenseCholesky() = default;
+
 std::unique_ptr<DenseCholesky> DenseCholesky::Create(
     const LinearSolver::Options& options) {
   std::unique_ptr<DenseCholesky> dense_cholesky;
diff --git a/internal/ceres/dense_cholesky.h b/internal/ceres/dense_cholesky.h
index a3514b4..a7bb80a 100644
--- a/internal/ceres/dense_cholesky.h
+++ b/internal/ceres/dense_cholesky.h
@@ -59,7 +59,7 @@
   static std::unique_ptr<DenseCholesky> Create(
       const LinearSolver::Options& options);
 
-  virtual ~DenseCholesky() = default;
+  virtual ~DenseCholesky();
 
   // Computes the Cholesky factorization of the given matrix.
   //
@@ -102,7 +102,6 @@
 
 class CERES_EXPORT_INTERNAL EigenDenseCholesky : public DenseCholesky {
  public:
-  ~EigenDenseCholesky() override = default;
 
   LinearSolverTerminationType Factorize(int num_cols,
                                         double* lhs,
@@ -119,7 +118,6 @@
 #ifndef CERES_NO_LAPACK
 class CERES_EXPORT_INTERNAL LAPACKDenseCholesky : public DenseCholesky {
  public:
-  ~LAPACKDenseCholesky() override = default;
 
   LinearSolverTerminationType Factorize(int num_cols,
                                         double* lhs,
diff --git a/internal/ceres/dense_qr.cc b/internal/ceres/dense_qr.cc
index 33831ea..33a7cbd 100644
--- a/internal/ceres/dense_qr.cc
+++ b/internal/ceres/dense_qr.cc
@@ -106,6 +106,8 @@
 namespace ceres {
 namespace internal {
 
+DenseQR::~DenseQR() = default;
+
 std::unique_ptr<DenseQR> DenseQR::Create(const LinearSolver::Options& options) {
   std::unique_ptr<DenseQR> dense_qr;
 
diff --git a/internal/ceres/dense_qr.h b/internal/ceres/dense_qr.h
index 93d890b..302fd4a 100644
--- a/internal/ceres/dense_qr.h
+++ b/internal/ceres/dense_qr.h
@@ -54,7 +54,7 @@
  public:
   static std::unique_ptr<DenseQR> Create(const LinearSolver::Options& options);
 
-  virtual ~DenseQR() = default;
+  virtual ~DenseQR();
 
   // Computes the QR factorization of the given matrix.
   //
@@ -98,7 +98,6 @@
 
 class CERES_EXPORT_INTERNAL EigenDenseQR : public DenseQR {
  public:
-  ~EigenDenseQR() override = default;
 
   LinearSolverTerminationType Factorize(int num_rows,
                                         int num_cols,
@@ -116,7 +115,6 @@
 #ifndef CERES_NO_LAPACK
 class CERES_EXPORT_INTERNAL LAPACKDenseQR : public DenseQR {
  public:
-  ~LAPACKDenseQR() override = default;
 
   LinearSolverTerminationType Factorize(int num_rows,
                                         int num_cols,
diff --git a/internal/ceres/dense_sparse_matrix.h b/internal/ceres/dense_sparse_matrix.h
index 5963322..1a61296 100644
--- a/internal/ceres/dense_sparse_matrix.h
+++ b/internal/ceres/dense_sparse_matrix.h
@@ -51,7 +51,6 @@
   explicit DenseSparseMatrix(const Matrix& m);
   DenseSparseMatrix(int num_rows, int num_cols);
 
-  ~DenseSparseMatrix() override = default;
 
   // SparseMatrix interface.
   void SetZero() final;
diff --git a/internal/ceres/dogleg_strategy.h b/internal/ceres/dogleg_strategy.h
index d79fb35..3ebf8bb 100644
--- a/internal/ceres/dogleg_strategy.h
+++ b/internal/ceres/dogleg_strategy.h
@@ -56,7 +56,6 @@
 class CERES_EXPORT_INTERNAL DoglegStrategy : public TrustRegionStrategy {
  public:
   explicit DoglegStrategy(const TrustRegionStrategy::Options& options);
-  ~DoglegStrategy() override = default;
 
   // TrustRegionStrategy interface
   Summary ComputeStep(const PerSolveOptions& per_solve_options,
diff --git a/internal/ceres/dynamic_sparse_normal_cholesky_solver.h b/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
index 6a2cb33..a6203c9 100644
--- a/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
+++ b/internal/ceres/dynamic_sparse_normal_cholesky_solver.h
@@ -58,7 +58,6 @@
  public:
   explicit DynamicSparseNormalCholeskySolver(
       const LinearSolver::Options& options);
-  ~DynamicSparseNormalCholeskySolver() override = default;
 
  private:
   LinearSolver::Summary SolveImpl(CompressedRowSparseMatrix* A,
diff --git a/internal/ceres/eigensparse.cc b/internal/ceres/eigensparse.cc
index ba8e05a..1a896cc 100644
--- a/internal/ceres/eigensparse.cc
+++ b/internal/ceres/eigensparse.cc
@@ -48,7 +48,6 @@
 class EigenSparseCholeskyTemplate : public SparseCholesky {
  public:
   EigenSparseCholeskyTemplate() : analyzed_(false) {}
-  ~EigenSparseCholeskyTemplate() override = default;
   CompressedRowSparseMatrix::StorageType StorageType() const final {
     return CompressedRowSparseMatrix::LOWER_TRIANGULAR;
   }
diff --git a/internal/ceres/evaluation_callback.cc b/internal/ceres/evaluation_callback.cc
new file mode 100644
index 0000000..77591a8
--- /dev/null
+++ b/internal/ceres/evaluation_callback.cc
@@ -0,0 +1,37 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2022 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: mierle@gmail.com (Keir Mierle)
+
+#include "ceres/evaluation_callback.h"
+
+namespace ceres {
+
+EvaluationCallback::~EvaluationCallback() = default;
+
+}  // namespace ceres
diff --git a/internal/ceres/evaluation_callback_test.cc b/internal/ceres/evaluation_callback_test.cc
index 84fff8a..adeb4da 100644
--- a/internal/ceres/evaluation_callback_test.cc
+++ b/internal/ceres/evaluation_callback_test.cc
@@ -72,7 +72,6 @@
         evaluate_num_calls(0),
         evaluate_last_parameter_hash(kUninitialized) {}
 
-  ~WigglyBowlCostFunctionAndEvaluationCallback() override = default;
 
   // Evaluation callback interface. This checks that all the preconditions are
   // met at the point that Ceres calls into it.
diff --git a/internal/ceres/first_order_function.cc b/internal/ceres/first_order_function.cc
new file mode 100644
index 0000000..26f1348
--- /dev/null
+++ b/internal/ceres/first_order_function.cc
@@ -0,0 +1,37 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2022 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/first_order_function.h"
+
+namespace ceres {
+
+FirstOrderFunction::~FirstOrderFunction() = default;
+
+}  // namespace ceres
diff --git a/internal/ceres/fixed_array_test.cc b/internal/ceres/fixed_array_test.cc
index 287230a..2982a98 100644
--- a/internal/ceres/fixed_array_test.cc
+++ b/internal/ceres/fixed_array_test.cc
@@ -500,8 +500,6 @@
 
 // PickyDelete EXPECTs its class-scope deallocation funcs are unused.
 struct PickyDelete {
-  PickyDelete() = default;
-  ~PickyDelete() = default;
   void operator delete(void* p) {
     EXPECT_TRUE(false) << __FUNCTION__;
     ::operator delete(p);
diff --git a/internal/ceres/generate_template_specializations.py b/internal/ceres/generate_template_specializations.py
index 74e46c2..617dcbf 100644
--- a/internal/ceres/generate_template_specializations.py
+++ b/internal/ceres/generate_template_specializations.py
@@ -85,9 +85,9 @@
   return str(size)
 
 def SpecializationFilename(prefix, row_block_size, e_block_size, f_block_size):
-  return "_".join([prefix] + map(SuffixForSize, (row_block_size,
+  return "_".join([prefix] + list(map(SuffixForSize, (row_block_size,
                                                  e_block_size,
-                                                 f_block_size)))
+                                                 f_block_size))))
 
 def GenerateFactoryConditional(row_block_size, e_block_size, f_block_size):
   conditionals = []
diff --git a/internal/ceres/gradient_checking_cost_function.cc b/internal/ceres/gradient_checking_cost_function.cc
index bbe68b8..1bb9ec9 100644
--- a/internal/ceres/gradient_checking_cost_function.cc
+++ b/internal/ceres/gradient_checking_cost_function.cc
@@ -80,7 +80,6 @@
     set_num_residuals(function->num_residuals());
   }
 
-  ~GradientCheckingCostFunction() override = default;
 
   bool Evaluate(double const* const* parameters,
                 double* residuals,
diff --git a/internal/ceres/gradient_checking_cost_function_test.cc b/internal/ceres/gradient_checking_cost_function_test.cc
index 5630c32..5e6b64c 100644
--- a/internal/ceres/gradient_checking_cost_function_test.cc
+++ b/internal/ceres/gradient_checking_cost_function_test.cc
@@ -268,7 +268,6 @@
     set_num_residuals(num_residuals);
     mutable_parameter_block_sizes()->push_back(parameter_block_size);
   }
-  ~UnaryCostFunction() override = default;
 
   bool Evaluate(double const* const* parameters,
                 double* residuals,
diff --git a/internal/ceres/gradient_problem_evaluator.h b/internal/ceres/gradient_problem_evaluator.h
index f0aba94..86611d0 100644
--- a/internal/ceres/gradient_problem_evaluator.h
+++ b/internal/ceres/gradient_problem_evaluator.h
@@ -50,7 +50,6 @@
   explicit GradientProblemEvaluator(const GradientProblem& problem)
       : problem_(problem) {}
 
-  ~GradientProblemEvaluator() override = default;
 
   std::unique_ptr<SparseMatrix> CreateJacobian() const final { return nullptr; }
 
diff --git a/internal/ceres/gradient_problem_solver_test.cc b/internal/ceres/gradient_problem_solver_test.cc
index 5e33b31..47a69f3 100644
--- a/internal/ceres/gradient_problem_solver_test.cc
+++ b/internal/ceres/gradient_problem_solver_test.cc
@@ -39,7 +39,6 @@
 // Rosenbrock function; see http://en.wikipedia.org/wiki/Rosenbrock_function .
 class Rosenbrock : public ceres::FirstOrderFunction {
  public:
-  ~Rosenbrock() override = default;
 
   bool Evaluate(const double* parameters,
                 double* cost,
@@ -73,7 +72,6 @@
 }
 
 class QuadraticFunction : public ceres::FirstOrderFunction {
-  ~QuadraticFunction() override = default;
   bool Evaluate(const double* parameters,
                 double* cost,
                 double* gradient) const final {
@@ -90,7 +88,6 @@
 
 struct RememberingCallback : public IterationCallback {
   explicit RememberingCallback(double* x) : calls(0), x(x) {}
-  ~RememberingCallback() override = default;
   CallbackReturnType operator()(const IterationSummary& summary) final {
     x_values.push_back(*x);
     return SOLVER_CONTINUE;
diff --git a/internal/ceres/graph.h b/internal/ceres/graph.h
index ef65453..685b267 100644
--- a/internal/ceres/graph.h
+++ b/internal/ceres/graph.h
@@ -49,7 +49,6 @@
 template <typename Vertex>
 class Graph {
  public:
-  Graph() = default;
 
   // Add a vertex.
   void AddVertex(const Vertex& vertex) {
@@ -106,7 +105,6 @@
 template <typename Vertex>
 class WeightedGraph {
  public:
-  WeightedGraph() = default;
 
   // Add a weighted vertex. If the vertex already exists in the graph,
   // its weight is set to the new weight.
diff --git a/internal/ceres/implicit_schur_complement.cc b/internal/ceres/implicit_schur_complement.cc
index 4e712b9..82a776c 100644
--- a/internal/ceres/implicit_schur_complement.cc
+++ b/internal/ceres/implicit_schur_complement.cc
@@ -45,8 +45,6 @@
     const LinearSolver::Options& options)
     : options_(options), D_(nullptr), b_(nullptr) {}
 
-ImplicitSchurComplement::~ImplicitSchurComplement() = default;
-
 void ImplicitSchurComplement::Init(const BlockSparseMatrix& A,
                                    const double* D,
                                    const double* b) {
diff --git a/internal/ceres/implicit_schur_complement.h b/internal/ceres/implicit_schur_complement.h
index 4ae76e5..b073706 100644
--- a/internal/ceres/implicit_schur_complement.h
+++ b/internal/ceres/implicit_schur_complement.h
@@ -100,7 +100,6 @@
   // TODO(sameeragarwal): Get rid of the two bools below and replace
   // them with enums.
   explicit ImplicitSchurComplement(const LinearSolver::Options& options);
-  ~ImplicitSchurComplement() override;
 
   // Initialize the Schur complement for a linear least squares
   // problem of the form
diff --git a/internal/ceres/iteration_callback.cc b/internal/ceres/iteration_callback.cc
new file mode 100644
index 0000000..804811d
--- /dev/null
+++ b/internal/ceres/iteration_callback.cc
@@ -0,0 +1,37 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2019 Google Inc. All rights reserved.
+// http://ceres-solver.org/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+//   this list of conditions and the following disclaimer in the documentation
+//   and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+//   used to endorse or promote products derived from this software without
+//   specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: sameeragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/iteration_callback.h"
+
+namespace ceres {
+
+IterationCallback::~IterationCallback() = default;
+
+}  // namespace ceres
diff --git a/internal/ceres/iterative_refiner_test.cc b/internal/ceres/iterative_refiner_test.cc
index d3ec9a2..5464a27 100644
--- a/internal/ceres/iterative_refiner_test.cc
+++ b/internal/ceres/iterative_refiner_test.cc
@@ -54,7 +54,6 @@
 class FakeSparseMatrix : public SparseMatrix {
  public:
   FakeSparseMatrix(const Matrix& m) : m_(m) {}
-  ~FakeSparseMatrix() override = default;
 
   // y += Ax
   void RightMultiply(const double* x, double* y) const final {
@@ -90,7 +89,6 @@
 class FakeSparseCholesky : public SparseCholesky {
  public:
   FakeSparseCholesky(const Matrix& lhs) { lhs_ = lhs.cast<Scalar>(); }
-  ~FakeSparseCholesky() override = default;
 
   LinearSolverTerminationType Solve(const double* rhs_ptr,
                                     double* solution_ptr,
diff --git a/internal/ceres/levenberg_marquardt_strategy_test.cc b/internal/ceres/levenberg_marquardt_strategy_test.cc
index dfb7302..818b7f5 100644
--- a/internal/ceres/levenberg_marquardt_strategy_test.cc
+++ b/internal/ceres/levenberg_marquardt_strategy_test.cc
@@ -58,7 +58,6 @@
   RegularizationCheckingLinearSolver(const int num_cols, const double* diagonal)
       : num_cols_(num_cols), diagonal_(diagonal) {}
 
-  ~RegularizationCheckingLinearSolver() override = default;
 
  private:
   LinearSolver::Summary SolveImpl(
diff --git a/internal/ceres/line_search.cc b/internal/ceres/line_search.cc
index 0141015..f8dbc8a 100644
--- a/internal/ceres/line_search.cc
+++ b/internal/ceres/line_search.cc
@@ -65,6 +65,8 @@
   return os;
 }
 
+LineSearch::~LineSearch() = default;
+
 LineSearch::LineSearch(const LineSearch::Options& options)
     : options_(options) {}
 
diff --git a/internal/ceres/line_search.h b/internal/ceres/line_search.h
index 7d1a852..958d71d 100644
--- a/internal/ceres/line_search.h
+++ b/internal/ceres/line_search.h
@@ -33,6 +33,7 @@
 #ifndef CERES_INTERNAL_LINE_SEARCH_H_
 #define CERES_INTERNAL_LINE_SEARCH_H_
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -161,7 +162,7 @@
   };
 
   explicit LineSearch(const LineSearch::Options& options);
-  virtual ~LineSearch() = default;
+  virtual ~LineSearch();
 
   static std::unique_ptr<LineSearch> Create(
       const LineSearchType line_search_type,
@@ -261,7 +262,6 @@
 class ArmijoLineSearch : public LineSearch {
  public:
   explicit ArmijoLineSearch(const LineSearch::Options& options);
-  ~ArmijoLineSearch() override = default;
 
  private:
   void DoSearch(double step_size_estimate,
@@ -280,7 +280,6 @@
 class WolfeLineSearch : public LineSearch {
  public:
   explicit WolfeLineSearch(const LineSearch::Options& options);
-  ~WolfeLineSearch() override = default;
 
   // Returns true iff either a valid point, or valid bracket are found.
   bool BracketingPhase(const FunctionSample& initial_position,
diff --git a/internal/ceres/line_search_direction.cc b/internal/ceres/line_search_direction.cc
index 4d6e641..8a71b56 100644
--- a/internal/ceres/line_search_direction.cc
+++ b/internal/ceres/line_search_direction.cc
@@ -40,7 +40,6 @@
 
 class SteepestDescent : public LineSearchDirection {
  public:
-  ~SteepestDescent() override = default;
   bool NextDirection(const LineSearchMinimizer::State& previous,
                      const LineSearchMinimizer::State& current,
                      Vector* search_direction) override {
@@ -105,7 +104,6 @@
                                   use_approximate_eigenvalue_bfgs_scaling),
         is_positive_definite_(true) {}
 
-  ~LBFGS() override = default;
 
   bool NextDirection(const LineSearchMinimizer::State& previous,
                      const LineSearchMinimizer::State& current,
@@ -161,7 +159,6 @@
     inverse_hessian_ = Matrix::Identity(num_parameters, num_parameters);
   }
 
-  ~BFGS() override = default;
 
   bool NextDirection(const LineSearchMinimizer::State& previous,
                      const LineSearchMinimizer::State& current,
@@ -338,6 +335,8 @@
   bool is_positive_definite_;
 };
 
+LineSearchDirection::~LineSearchDirection() = default;
+
 std::unique_ptr<LineSearchDirection> LineSearchDirection::Create(
     const LineSearchDirection::Options& options) {
   if (options.type == STEEPEST_DESCENT) {
diff --git a/internal/ceres/line_search_direction.h b/internal/ceres/line_search_direction.h
index 29127c1..11d56bc 100644
--- a/internal/ceres/line_search_direction.h
+++ b/internal/ceres/line_search_direction.h
@@ -59,7 +59,7 @@
 
   static std::unique_ptr<LineSearchDirection> Create(const Options& options);
 
-  virtual ~LineSearchDirection() = default;
+  virtual ~LineSearchDirection();
   virtual bool NextDirection(const LineSearchMinimizer::State& previous,
                              const LineSearchMinimizer::State& current,
                              Vector* search_direction) = 0;
diff --git a/internal/ceres/line_search_minimizer.h b/internal/ceres/line_search_minimizer.h
index ae4670a..75928f8 100644
--- a/internal/ceres/line_search_minimizer.h
+++ b/internal/ceres/line_search_minimizer.h
@@ -63,7 +63,6 @@
     double step_size;
   };
 
-  ~LineSearchMinimizer() override = default;
   void Minimize(const Minimizer::Options& options,
                 double* parameters,
                 Solver::Summary* summary) final;
diff --git a/internal/ceres/line_search_preprocessor.cc b/internal/ceres/line_search_preprocessor.cc
index 02a1a8c..26b8d99 100644
--- a/internal/ceres/line_search_preprocessor.cc
+++ b/internal/ceres/line_search_preprocessor.cc
@@ -70,8 +70,6 @@
 
 }  // namespace
 
-LineSearchPreprocessor::~LineSearchPreprocessor() = default;
-
 bool LineSearchPreprocessor::Preprocess(const Solver::Options& options,
                                         ProblemImpl* problem,
                                         PreprocessedProblem* pp) {
diff --git a/internal/ceres/line_search_preprocessor.h b/internal/ceres/line_search_preprocessor.h
index 1ba7076..cdce438 100644
--- a/internal/ceres/line_search_preprocessor.h
+++ b/internal/ceres/line_search_preprocessor.h
@@ -39,7 +39,6 @@
 
 class CERES_EXPORT_INTERNAL LineSearchPreprocessor : public Preprocessor {
  public:
-  ~LineSearchPreprocessor() override;
   bool Preprocess(const Solver::Options& options,
                   ProblemImpl* problem,
                   PreprocessedProblem* preprocessed_problem) final;
diff --git a/internal/ceres/linear_solver.h b/internal/ceres/linear_solver.h
index ea44f3b..9905af0 100644
--- a/internal/ceres/linear_solver.h
+++ b/internal/ceres/linear_solver.h
@@ -301,7 +301,6 @@
 template <typename MatrixType>
 class TypedLinearSolver : public LinearSolver {
  public:
-  ~TypedLinearSolver() override = default;
   LinearSolver::Summary Solve(
       LinearOperator* A,
       const double* b,
diff --git a/internal/ceres/loss_function.cc b/internal/ceres/loss_function.cc
index f4ea0f7..3392b3b 100644
--- a/internal/ceres/loss_function.cc
+++ b/internal/ceres/loss_function.cc
@@ -39,6 +39,8 @@
 
 namespace ceres {
 
+LossFunction::~LossFunction() = default;
+
 void TrivialLoss::Evaluate(double s, double rho[3]) const {
   rho[0] = s;
   rho[1] = 1.0;
diff --git a/internal/ceres/low_rank_inverse_hessian.h b/internal/ceres/low_rank_inverse_hessian.h
index a7a572c..00414b7 100644
--- a/internal/ceres/low_rank_inverse_hessian.h
+++ b/internal/ceres/low_rank_inverse_hessian.h
@@ -73,7 +73,6 @@
   LowRankInverseHessian(int num_parameters,
                         int max_num_corrections,
                         bool use_approximate_eigenvalue_scaling);
-  ~LowRankInverseHessian() override = default;
 
   // Update the low rank approximation. delta_x is the change in the
   // domain of Hessian, and delta_gradient is the change in the
diff --git a/internal/ceres/manifold.cc b/internal/ceres/manifold.cc
index 8c81a99..451286a 100644
--- a/internal/ceres/manifold.cc
+++ b/internal/ceres/manifold.cc
@@ -137,6 +137,8 @@
 
 }  // namespace
 
+Manifold::~Manifold() = default;
+
 bool Manifold::RightMultiplyByPlusJacobian(const double* x,
                                            const int num_rows,
                                            const double* ambient_matrix,
diff --git a/internal/ceres/manifold_adapter.h b/internal/ceres/manifold_adapter.h
index 2efec3a..5aa2005 100644
--- a/internal/ceres/manifold_adapter.h
+++ b/internal/ceres/manifold_adapter.h
@@ -15,7 +15,6 @@
     CHECK(local_parameterization != nullptr);
   }
 
-  ~ManifoldAdapter() override = default;
 
   bool Plus(const double* x,
             const double* delta,
diff --git a/internal/ceres/miniglog/glog/logging.h b/internal/ceres/miniglog/glog/logging.h
index 34f26a5..67ca18a 100644
--- a/internal/ceres/miniglog/glog/logging.h
+++ b/internal/ceres/miniglog/glog/logging.h
@@ -294,7 +294,6 @@
 // is not used" and "statement has no effect".
 class CERES_EXPORT LoggerVoidify {
  public:
-  LoggerVoidify() = default;
   // This has to be an operator with a precedence lower than << but
   // higher than ?:
   void operator&(const std::ostream& s) {}
diff --git a/internal/ceres/minimizer_test.cc b/internal/ceres/minimizer_test.cc
index 909beab..8ddf126 100644
--- a/internal/ceres/minimizer_test.cc
+++ b/internal/ceres/minimizer_test.cc
@@ -39,7 +39,6 @@
 
 class FakeIterationCallback : public IterationCallback {
  public:
-  ~FakeIterationCallback() override = default;
   CallbackReturnType operator()(const IterationSummary& summary) final {
     return SOLVER_CONTINUE;
   }
@@ -62,7 +61,6 @@
 
 class AbortingIterationCallback : public IterationCallback {
  public:
-  ~AbortingIterationCallback() override = default;
   CallbackReturnType operator()(const IterationSummary& summary) final {
     return SOLVER_ABORT;
   }
@@ -80,7 +78,6 @@
 
 class SucceedingIterationCallback : public IterationCallback {
  public:
-  ~SucceedingIterationCallback() override = default;
   CallbackReturnType operator()(const IterationSummary& summary) final {
     return SOLVER_TERMINATE_SUCCESSFULLY;
   }
diff --git a/internal/ceres/parameter_block_test.cc b/internal/ceres/parameter_block_test.cc
index e0da433..a532a9a 100644
--- a/internal/ceres/parameter_block_test.cc
+++ b/internal/ceres/parameter_block_test.cc
@@ -111,7 +111,6 @@
 
 struct TestManifold : public Manifold {
  public:
-  ~TestManifold() final = default;
 
   bool Plus(const double* x,
             const double* delta,
@@ -166,7 +165,6 @@
 class BadManifold : public Manifold {
  public:
   BadManifold() : calls_(0) {}
-  ~BadManifold() final = default;
 
   bool Plus(const double* x,
             const double* delta,
diff --git a/internal/ceres/partitioned_matrix_view.cc b/internal/ceres/partitioned_matrix_view.cc
index 595b701..0d81c02 100644
--- a/internal/ceres/partitioned_matrix_view.cc
+++ b/internal/ceres/partitioned_matrix_view.cc
@@ -45,6 +45,8 @@
 namespace ceres {
 namespace internal {
 
+PartitionedMatrixViewBase::~PartitionedMatrixViewBase() = default;
+
 std::unique_ptr<PartitionedMatrixViewBase> PartitionedMatrixViewBase::Create(
     const LinearSolver::Options& options, const BlockSparseMatrix& matrix) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
diff --git a/internal/ceres/partitioned_matrix_view.h b/internal/ceres/partitioned_matrix_view.h
index 36cf0d4..d9ebcd9 100644
--- a/internal/ceres/partitioned_matrix_view.h
+++ b/internal/ceres/partitioned_matrix_view.h
@@ -62,7 +62,7 @@
 // wrong output.
 class CERES_EXPORT_INTERNAL PartitionedMatrixViewBase {
  public:
-  virtual ~PartitionedMatrixViewBase() = default;
+  virtual ~PartitionedMatrixViewBase();
 
   // y += E'x
   virtual void LeftMultiplyE(const double* x, double* y) const = 0;
@@ -121,7 +121,6 @@
   // num_col_blocks_a column blocks.
   PartitionedMatrixView(const BlockSparseMatrix& matrix, int num_col_blocks_e);
 
-  ~PartitionedMatrixView() override;
   void LeftMultiplyE(const double* x, double* y) const final;
   void LeftMultiplyF(const double* x, double* y) const final;
   void RightMultiplyE(const double* x, double* y) const final;
diff --git a/internal/ceres/partitioned_matrix_view_impl.h b/internal/ceres/partitioned_matrix_view_impl.h
index 4dd8d70..753e0f9 100644
--- a/internal/ceres/partitioned_matrix_view_impl.h
+++ b/internal/ceres/partitioned_matrix_view_impl.h
@@ -80,10 +80,6 @@
   CHECK_EQ(num_cols_e_ + num_cols_f_, matrix_.num_cols());
 }
 
-template <int kRowBlockSize, int kEBlockSize, int kFBlockSize>
-PartitionedMatrixView<kRowBlockSize, kEBlockSize, kFBlockSize>::
-    ~PartitionedMatrixView() = default;
-
 // The next four methods don't seem to be particularly cache
 // friendly. This is an artifact of how the BlockStructure of the
 // input matrix is constructed. These methods will benefit from
diff --git a/internal/ceres/partitioned_matrix_view_template.py b/internal/ceres/partitioned_matrix_view_template.py
index 9ab56cf..42a135f 100644
--- a/internal/ceres/partitioned_matrix_view_template.py
+++ b/internal/ceres/partitioned_matrix_view_template.py
@@ -128,6 +128,8 @@
 namespace ceres {
 namespace internal {
 
+PartitionedMatrixViewBase::~PartitionedMatrixViewBase() = default;
+
 std::unique_ptr<PartitionedMatrixViewBase> PartitionedMatrixViewBase::Create(
     const LinearSolver::Options& options, const BlockSparseMatrix& matrix) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
diff --git a/internal/ceres/preconditioner.h b/internal/ceres/preconditioner.h
index e0eb88d..04dffef 100644
--- a/internal/ceres/preconditioner.h
+++ b/internal/ceres/preconditioner.h
@@ -149,7 +149,6 @@
 template <typename MatrixType>
 class TypedPreconditioner : public Preconditioner {
  public:
-  ~TypedPreconditioner() override = default;
   bool Update(const LinearOperator& A, const double* D) final {
     return UpdateImpl(*down_cast<const MatrixType*>(&A), D);
   }
diff --git a/internal/ceres/problem_test.cc b/internal/ceres/problem_test.cc
index 1987e13..9a73034 100644
--- a/internal/ceres/problem_test.cc
+++ b/internal/ceres/problem_test.cc
@@ -67,7 +67,6 @@
     mutable_parameter_block_sizes()->push_back(parameter_block_size);
   }
 
-  ~UnaryCostFunction() override = default;
 
   bool Evaluate(double const* const* parameters,
                 double* residuals,
diff --git a/internal/ceres/program.cc b/internal/ceres/program.cc
index adfff0b..e65ffcd 100644
--- a/internal/ceres/program.cc
+++ b/internal/ceres/program.cc
@@ -54,11 +54,6 @@
 namespace ceres {
 namespace internal {
 
-Program::Program() = default;
-
-Program::Program(const Program& program)
-
-    = default;
 
 const std::vector<ParameterBlock*>& Program::parameter_blocks() const {
   return parameter_blocks_;
diff --git a/internal/ceres/program.h b/internal/ceres/program.h
index ffd5db7..82ae130 100644
--- a/internal/ceres/program.h
+++ b/internal/ceres/program.h
@@ -59,9 +59,6 @@
 // not built for transformation.
 class CERES_EXPORT_INTERNAL Program {
  public:
-  Program();
-  explicit Program(const Program& program);
-
   // The ordered parameter and residual blocks for the program.
   const std::vector<ParameterBlock*>& parameter_blocks() const;
   const std::vector<ResidualBlock*>& residual_blocks() const;
diff --git a/internal/ceres/program_test.cc b/internal/ceres/program_test.cc
index d12cfa5..8f1c422 100644
--- a/internal/ceres/program_test.cc
+++ b/internal/ceres/program_test.cc
@@ -331,7 +331,6 @@
     }
   }
 
-  ~NumParameterBlocksCostFunction() override = default;
 
   bool Evaluate(double const* const* parameters,
                 double* residuals,
diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc
index 15c1629..adc1531 100644
--- a/internal/ceres/schur_complement_solver.cc
+++ b/internal/ceres/schur_complement_solver.cc
@@ -68,7 +68,6 @@
       const BlockRandomAccessSparseMatrix& m)
       : m_(m) {}
 
-  ~BlockRandomAccessSparseMatrixAdapter() override = default;
 
   // y = y + Ax;
   void RightMultiply(const double* x, double* y) const final {
@@ -93,7 +92,6 @@
       const BlockRandomAccessDiagonalMatrix& m)
       : m_(m) {}
 
-  ~BlockRandomAccessDiagonalMatrixAdapter() override = default;
 
   // y = y + Ax;
   void RightMultiply(const double* x, double* y) const final {
@@ -122,8 +120,6 @@
   CHECK(options.context != nullptr);
 }
 
-SchurComplementSolver::~SchurComplementSolver() = default;
-
 LinearSolver::Summary SchurComplementSolver::SolveImpl(
     BlockSparseMatrix* A,
     const double* b,
diff --git a/internal/ceres/schur_complement_solver.h b/internal/ceres/schur_complement_solver.h
index 3d343bf..2060cc8 100644
--- a/internal/ceres/schur_complement_solver.h
+++ b/internal/ceres/schur_complement_solver.h
@@ -115,7 +115,6 @@
   SchurComplementSolver(const SchurComplementSolver&) = delete;
   void operator=(const SchurComplementSolver&) = delete;
 
-  ~SchurComplementSolver() override;
   LinearSolver::Summary SolveImpl(
       BlockSparseMatrix* A,
       const double* b,
diff --git a/internal/ceres/schur_eliminator.cc b/internal/ceres/schur_eliminator.cc
index bcffbe6..de0e950 100644
--- a/internal/ceres/schur_eliminator.cc
+++ b/internal/ceres/schur_eliminator.cc
@@ -45,6 +45,8 @@
 namespace ceres {
 namespace internal {
 
+SchurEliminatorBase::~SchurEliminatorBase() = default;
+
 std::unique_ptr<SchurEliminatorBase> SchurEliminatorBase::Create(
     const LinearSolver::Options& options) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
diff --git a/internal/ceres/schur_eliminator.h b/internal/ceres/schur_eliminator.h
index cf7a3e4..dd3d4b2 100644
--- a/internal/ceres/schur_eliminator.h
+++ b/internal/ceres/schur_eliminator.h
@@ -165,7 +165,7 @@
 // Example usage: Please see schur_complement_solver.cc
 class CERES_EXPORT_INTERNAL SchurEliminatorBase {
  public:
-  virtual ~SchurEliminatorBase() = default;
+  virtual ~SchurEliminatorBase();
 
   // Initialize the eliminator. It is the user's responsibilty to call
   // this function before calling Eliminate or BackSubstitute. It is
@@ -380,7 +380,6 @@
           int kFBlockSize = Eigen::Dynamic>
 class SchurEliminatorForOneFBlock : public SchurEliminatorBase {
  public:
-  ~SchurEliminatorForOneFBlock() override = default;
   void Init(int num_eliminate_blocks,
             bool assume_full_rank_ete,
             const CompressedRowBlockStructure* bs) override {
diff --git a/internal/ceres/schur_eliminator_template.py b/internal/ceres/schur_eliminator_template.py
index a6a8d56..0bddb29 100644
--- a/internal/ceres/schur_eliminator_template.py
+++ b/internal/ceres/schur_eliminator_template.py
@@ -130,6 +130,8 @@
 namespace ceres {
 namespace internal {
 
+SchurEliminatorBase::~SchurEliminatorBase() = default;
+
 std::unique_ptr<SchurEliminatorBase> SchurEliminatorBase::Create(
     const LinearSolver::Options& options) {
 #ifndef CERES_RESTRICT_SCHUR_SPECIALIZATION
diff --git a/internal/ceres/solver_test.cc b/internal/ceres/solver_test.cc
index 41f3872..3ecde20 100644
--- a/internal/ceres/solver_test.cc
+++ b/internal/ceres/solver_test.cc
@@ -78,7 +78,6 @@
 
 struct RememberingCallback : public IterationCallback {
   explicit RememberingCallback(double* x) : calls(0), x(x) {}
-  ~RememberingCallback() override = default;
   CallbackReturnType operator()(const IterationSummary& summary) final {
     x_values.push_back(*x);
     return SOLVER_CONTINUE;
@@ -89,7 +88,6 @@
 };
 
 struct NoOpEvaluationCallback : EvaluationCallback {
-  ~NoOpEvaluationCallback() override = default;
   void PrepareForEvaluation(bool evaluate_jacobians,
                             bool new_evaluation_point) final {
     (void)evaluate_jacobians;
diff --git a/internal/ceres/trust_region_minimizer_test.cc b/internal/ceres/trust_region_minimizer_test.cc
index d42aab0..62261f7 100644
--- a/internal/ceres/trust_region_minimizer_test.cc
+++ b/internal/ceres/trust_region_minimizer_test.cc
@@ -76,7 +76,6 @@
   }
   // clang-format on
 
-  ~PowellEvaluator2() override = default;
 
   // Implementation of Evaluator interface.
   std::unique_ptr<SparseMatrix> CreateJacobian() const final {