Add final specifier to internal classes.

This should help the compiler devirtualize a bunch of function
calls.

https://github.com/ceres-solver/ceres-solver/issues/747

Change-Id: I9913e68d85e0e9c9f955a249cc710a657875c869
diff --git a/internal/ceres/accelerate_sparse.h b/internal/ceres/accelerate_sparse.h
index 7d52294..29d78e8 100644
--- a/internal/ceres/accelerate_sparse.h
+++ b/internal/ceres/accelerate_sparse.h
@@ -111,7 +111,7 @@
 // An implementation of SparseCholesky interface using Apple's Accelerate
 // framework.
 template <typename Scalar>
-class AppleAccelerateCholesky : public SparseCholesky {
+class AppleAccelerateCholesky final : public SparseCholesky {
  public:
   // Factory
   static std::unique_ptr<SparseCholesky> Create(OrderingType ordering_type);
diff --git a/internal/ceres/block_sparse_matrix.h b/internal/ceres/block_sparse_matrix.h
index df8382d..8e555b0 100644
--- a/internal/ceres/block_sparse_matrix.h
+++ b/internal/ceres/block_sparse_matrix.h
@@ -55,7 +55,7 @@
 //
 //   internal/ceres/block_structure.h
 //
-class CERES_NO_EXPORT BlockSparseMatrix : public SparseMatrix {
+class CERES_NO_EXPORT BlockSparseMatrix final : public SparseMatrix {
  public:
   // Construct a block sparse matrix with a fully initialized
   // CompressedRowBlockStructure objected. The matrix takes over
diff --git a/internal/ceres/c_api.cc b/internal/ceres/c_api.cc
index 9a0fd9c..784504f 100644
--- a/internal/ceres/c_api.cc
+++ b/internal/ceres/c_api.cc
@@ -65,7 +65,7 @@
 
 // This cost function wraps a C-level function pointer from the user, to bridge
 // between C and C++.
-class CERES_NO_EXPORT CallbackCostFunction : public ceres::CostFunction {
+class CERES_NO_EXPORT CallbackCostFunction final : public ceres::CostFunction {
  public:
   CallbackCostFunction(ceres_cost_function_t cost_function,
                        void* user_data,
@@ -93,7 +93,7 @@
 
 // This loss function wraps a C-level function pointer from the user, to bridge
 // between C and C++.
-class CallbackLossFunction : public ceres::LossFunction {
+class CallbackLossFunction final : public ceres::LossFunction {
  public:
   explicit CallbackLossFunction(ceres_loss_function_t loss_function,
                                 void* user_data)
diff --git a/internal/ceres/callbacks.h b/internal/ceres/callbacks.h
index 883de05..3b1d10c 100644
--- a/internal/ceres/callbacks.h
+++ b/internal/ceres/callbacks.h
@@ -43,7 +43,7 @@
 
 // Callback for updating the externally visible state of parameter
 // blocks.
-class CERES_NO_EXPORT StateUpdatingCallback : public IterationCallback {
+class CERES_NO_EXPORT StateUpdatingCallback final : public IterationCallback {
  public:
   StateUpdatingCallback(Program* program, double* parameters);
   ~StateUpdatingCallback() override;
@@ -56,7 +56,7 @@
 
 // Callback for updating the externally visible state of the
 // parameters vector for GradientProblemSolver.
-class CERES_NO_EXPORT GradientProblemSolverStateUpdatingCallback
+class CERES_NO_EXPORT GradientProblemSolverStateUpdatingCallback final
     : public IterationCallback {
  public:
   GradientProblemSolverStateUpdatingCallback(int num_parameters,
@@ -73,7 +73,7 @@
 
 // Callback for logging the state of the minimizer to STDERR or
 // STDOUT depending on the user's preferences and logging level.
-class CERES_NO_EXPORT LoggingCallback : public IterationCallback {
+class CERES_NO_EXPORT LoggingCallback final : public IterationCallback {
  public:
   LoggingCallback(MinimizerType minimizer_type, bool log_to_stdout);
   ~LoggingCallback() override;
diff --git a/internal/ceres/cgnr_linear_operator.h b/internal/ceres/cgnr_linear_operator.h
index f4e8b7e..d708efc 100644
--- a/internal/ceres/cgnr_linear_operator.h
+++ b/internal/ceres/cgnr_linear_operator.h
@@ -80,7 +80,7 @@
 //  and z = A^T b
 //
 // Note: This class is not thread safe, since it uses some temporary storage.
-class CERES_NO_EXPORT CgnrLinearOperator : public LinearOperator {
+class CERES_NO_EXPORT CgnrLinearOperator final : public LinearOperator {
  public:
   CgnrLinearOperator(const LinearOperator& A, const double* D)
       : A_(A), D_(D), z_(new double[A.num_rows()]) {}
diff --git a/internal/ceres/cgnr_solver.h b/internal/ceres/cgnr_solver.h
index e7c2f74..06a6118 100644
--- a/internal/ceres/cgnr_solver.h
+++ b/internal/ceres/cgnr_solver.h
@@ -50,7 +50,7 @@
 //
 // as required for solving for x in the least squares sense. Currently only
 // block diagonal preconditioning is supported.
-class CERES_NO_EXPORT CgnrSolver : public BlockSparseMatrixSolver {
+class CERES_NO_EXPORT CgnrSolver final : public BlockSparseMatrixSolver {
  public:
   explicit CgnrSolver(const LinearSolver::Options& options);
   CgnrSolver(const CgnrSolver&) = delete;
diff --git a/internal/ceres/conjugate_gradients_solver.h b/internal/ceres/conjugate_gradients_solver.h
index eb954e6..418508a 100644
--- a/internal/ceres/conjugate_gradients_solver.h
+++ b/internal/ceres/conjugate_gradients_solver.h
@@ -56,7 +56,7 @@
 // For more details see the documentation for
 // LinearSolver::PerSolveOptions::r_tolerance and
 // LinearSolver::PerSolveOptions::q_tolerance in linear_solver.h.
-class CERES_NO_EXPORT ConjugateGradientsSolver : public LinearSolver {
+class CERES_NO_EXPORT ConjugateGradientsSolver final : public LinearSolver {
  public:
   explicit ConjugateGradientsSolver(const LinearSolver::Options& options);
   Summary Solve(LinearOperator* A,
diff --git a/internal/ceres/context_impl.h b/internal/ceres/context_impl.h
index 1944549..7c49ba6 100644
--- a/internal/ceres/context_impl.h
+++ b/internal/ceres/context_impl.h
@@ -53,7 +53,7 @@
 namespace ceres {
 namespace internal {
 
-class CERES_NO_EXPORT ContextImpl : public Context {
+class CERES_NO_EXPORT ContextImpl final : public Context {
  public:
   ContextImpl();
   ~ContextImpl() override;
diff --git a/internal/ceres/coordinate_descent_minimizer.h b/internal/ceres/coordinate_descent_minimizer.h
index d781491..75f2648 100644
--- a/internal/ceres/coordinate_descent_minimizer.h
+++ b/internal/ceres/coordinate_descent_minimizer.h
@@ -56,7 +56,7 @@
 //
 // The minimizer assumes that none of the parameter blocks in the
 // program are constant.
-class CERES_NO_EXPORT CoordinateDescentMinimizer : public Minimizer {
+class CERES_NO_EXPORT CoordinateDescentMinimizer final : public Minimizer {
  public:
   explicit CoordinateDescentMinimizer(ContextImpl* context);
 
diff --git a/internal/ceres/cxsparse.h b/internal/ceres/cxsparse.h
index 8968bba..74135f9 100644
--- a/internal/ceres/cxsparse.h
+++ b/internal/ceres/cxsparse.h
@@ -139,7 +139,7 @@
 
 // An implementation of SparseCholesky interface using the CXSparse
 // library.
-class CERES_NO_EXPORT CXSparseCholesky : public SparseCholesky {
+class CERES_NO_EXPORT CXSparseCholesky final : public SparseCholesky {
  public:
   // Factory
   static std::unique_ptr<SparseCholesky> Create(OrderingType ordering_type);
diff --git a/internal/ceres/dense_cholesky.h b/internal/ceres/dense_cholesky.h
index b40e69a..d056d85 100644
--- a/internal/ceres/dense_cholesky.h
+++ b/internal/ceres/dense_cholesky.h
@@ -101,9 +101,8 @@
                                              std::string* message);
 };
 
-class CERES_NO_EXPORT EigenDenseCholesky : public DenseCholesky {
+class CERES_NO_EXPORT EigenDenseCholesky final : public DenseCholesky {
  public:
-
   LinearSolverTerminationType Factorize(int num_cols,
                                         double* lhs,
                                         std::string* message) override;
@@ -117,9 +116,8 @@
 };
 
 #ifndef CERES_NO_LAPACK
-class CERES_NO_EXPORT LAPACKDenseCholesky : public DenseCholesky {
+class CERES_NO_EXPORT LAPACKDenseCholesky final : public DenseCholesky {
  public:
-
   LinearSolverTerminationType Factorize(int num_cols,
                                         double* lhs,
                                         std::string* message) override;
@@ -137,7 +135,7 @@
 #ifndef CERES_NO_CUDA
 // CUDA implementation of DenseCholesky using the cuSolverDN library using the
 // 32-bit legacy interface for maximum compatibility.
-class CERES_NO_EXPORT CUDADenseCholesky : public DenseCholesky {
+class CERES_NO_EXPORT CUDADenseCholesky final : public DenseCholesky {
  public:
   static std::unique_ptr<CUDADenseCholesky> Create(
       const LinearSolver::Options& options);
@@ -174,8 +172,7 @@
   CudaBuffer<int> error_;
   // Cache the result of Factorize to ensure that when Solve is called, the
   // factiorization of lhs is valid.
-  LinearSolverTerminationType factorize_result_ =
-      LINEAR_SOLVER_FATAL_ERROR;
+  LinearSolverTerminationType factorize_result_ = LINEAR_SOLVER_FATAL_ERROR;
 };
 
 #endif  // CERES_NO_CUDA
diff --git a/internal/ceres/dense_qr.h b/internal/ceres/dense_qr.h
index d42cf8c..1a3bc81 100644
--- a/internal/ceres/dense_qr.h
+++ b/internal/ceres/dense_qr.h
@@ -49,8 +49,8 @@
 #ifndef CERES_NO_CUDA
 #include "ceres/context_impl.h"
 #include "ceres/cuda_buffer.h"
-#include "cuda_runtime.h"
 #include "cublas_v2.h"
+#include "cuda_runtime.h"
 #include "cusolverDn.h"
 #endif  // CERES_NO_CUDA
 
@@ -106,9 +106,8 @@
                                              std::string* message);
 };
 
-class CERES_NO_EXPORT EigenDenseQR : public DenseQR {
+class CERES_NO_EXPORT EigenDenseQR final : public DenseQR {
  public:
-
   LinearSolverTerminationType Factorize(int num_rows,
                                         int num_cols,
                                         double* lhs,
@@ -123,9 +122,8 @@
 };
 
 #ifndef CERES_NO_LAPACK
-class CERES_NO_EXPORT LAPACKDenseQR : public DenseQR {
+class CERES_NO_EXPORT LAPACKDenseQR final : public DenseQR {
  public:
-
   LinearSolverTerminationType Factorize(int num_rows,
                                         int num_cols,
                                         double* lhs,
@@ -151,7 +149,7 @@
 // This is because cuSolverDn does not implement the singularity-checking
 // wrapper trtrs, hence this solver directly uses trsv from CUBLAS for the
 // backsubstitution.
-class CERES_NO_EXPORT CUDADenseQR : public DenseQR {
+class CERES_NO_EXPORT CUDADenseQR final : public DenseQR {
  public:
   static std::unique_ptr<CUDADenseQR> Create(
       const LinearSolver::Options& options);
@@ -170,7 +168,7 @@
   // Picks up the cuSolverDN, cuBLAS, and cuStream handles from the context. If
   // the context is unable to initialize CUDA, returns false with a
   // human-readable message indicating the reason.
-  bool Init(ContextImpl* context,std::string* message);
+  bool Init(ContextImpl* context, std::string* message);
 
   // Handle to the cuSOLVER context.
   cusolverDnHandle_t cusolver_handle_ = nullptr;
@@ -196,8 +194,7 @@
   CudaBuffer<int> error_;
   // Cache the result of Factorize to ensure that when Solve is called, the
   // factiorization of lhs is valid.
-  LinearSolverTerminationType factorize_result_ =
-      LINEAR_SOLVER_FATAL_ERROR;
+  LinearSolverTerminationType factorize_result_ = LINEAR_SOLVER_FATAL_ERROR;
 };
 
 #endif  // CERES_NO_CUDA
diff --git a/internal/ceres/dense_qr_solver.h b/internal/ceres/dense_qr_solver.h
index 0dd91c1..39922a2 100644
--- a/internal/ceres/dense_qr_solver.h
+++ b/internal/ceres/dense_qr_solver.h
@@ -83,7 +83,7 @@
 // library. This solver always returns a solution, it is the user's
 // responsibility to judge if the solution is good enough for their
 // purposes.
-class CERES_NO_EXPORT DenseQRSolver : public DenseSparseMatrixSolver {
+class CERES_NO_EXPORT DenseQRSolver final : public DenseSparseMatrixSolver {
  public:
   explicit DenseQRSolver(const LinearSolver::Options& options);
 
diff --git a/internal/ceres/dense_sparse_matrix.h b/internal/ceres/dense_sparse_matrix.h
index 606c38c..9f0835b 100644
--- a/internal/ceres/dense_sparse_matrix.h
+++ b/internal/ceres/dense_sparse_matrix.h
@@ -44,7 +44,7 @@
 
 class TripletSparseMatrix;
 
-class CERES_NO_EXPORT DenseSparseMatrix : public SparseMatrix {
+class CERES_NO_EXPORT DenseSparseMatrix final : public SparseMatrix {
  public:
   // Build a matrix with the same content as the TripletSparseMatrix
   // m. This assumes that m does not have any repeated entries.
@@ -52,7 +52,6 @@
   explicit DenseSparseMatrix(const Matrix& m);
   DenseSparseMatrix(int num_rows, int num_cols);
 
-
   // SparseMatrix interface.
   void SetZero() final;
   void RightMultiply(const double* x, double* y) const final;
diff --git a/internal/ceres/dogleg_strategy.h b/internal/ceres/dogleg_strategy.h
index 2d04a49..17f0cc7 100644
--- a/internal/ceres/dogleg_strategy.h
+++ b/internal/ceres/dogleg_strategy.h
@@ -54,7 +54,7 @@
 // DoglegStrategy follows the approach by Shultz, Schnabel, Byrd.
 // This finds the exact optimum over the two-dimensional subspace
 // spanned by the two Dogleg vectors.
-class CERES_NO_EXPORT DoglegStrategy : public TrustRegionStrategy {
+class CERES_NO_EXPORT DoglegStrategy final : public TrustRegionStrategy {
  public:
   explicit DoglegStrategy(const TrustRegionStrategy::Options& options);
 
diff --git a/internal/ceres/dynamic_compressed_row_sparse_matrix.h b/internal/ceres/dynamic_compressed_row_sparse_matrix.h
index 11f78c7..5b4c402 100644
--- a/internal/ceres/dynamic_compressed_row_sparse_matrix.h
+++ b/internal/ceres/dynamic_compressed_row_sparse_matrix.h
@@ -50,7 +50,7 @@
 namespace ceres {
 namespace internal {
 
-class CERES_NO_EXPORT DynamicCompressedRowSparseMatrix
+class CERES_NO_EXPORT DynamicCompressedRowSparseMatrix final
     : public CompressedRowSparseMatrix {
  public:
   // Set the number of rows and columns for the underlyig
diff --git a/internal/ceres/eigensparse.cc b/internal/ceres/eigensparse.cc
index 7211450..38055dc 100644
--- a/internal/ceres/eigensparse.cc
+++ b/internal/ceres/eigensparse.cc
@@ -47,7 +47,7 @@
 // TODO(sameeragarwal): Use enable_if to clean up the implementations
 // for when Scalar == double.
 template <typename Solver>
-class EigenSparseCholeskyTemplate : public SparseCholesky {
+class EigenSparseCholeskyTemplate final : public SparseCholesky {
  public:
   EigenSparseCholeskyTemplate() : analyzed_(false) {}
   CompressedRowSparseMatrix::StorageType StorageType() const final {
diff --git a/internal/ceres/gradient_checking_cost_function.cc b/internal/ceres/gradient_checking_cost_function.cc
index e322b7c..3251806 100644
--- a/internal/ceres/gradient_checking_cost_function.cc
+++ b/internal/ceres/gradient_checking_cost_function.cc
@@ -61,7 +61,7 @@
 
 namespace {
 
-class GradientCheckingCostFunction : public CostFunction {
+class GradientCheckingCostFunction final : public CostFunction {
  public:
   GradientCheckingCostFunction(const CostFunction* function,
                                const std::vector<const Manifold*>* manifolds,
diff --git a/internal/ceres/gradient_problem_evaluator.h b/internal/ceres/gradient_problem_evaluator.h
index 70b794f..efbb257 100644
--- a/internal/ceres/gradient_problem_evaluator.h
+++ b/internal/ceres/gradient_problem_evaluator.h
@@ -46,12 +46,11 @@
 namespace ceres {
 namespace internal {
 
-class CERES_NO_EXPORT GradientProblemEvaluator : public Evaluator {
+class CERES_NO_EXPORT GradientProblemEvaluator final : public Evaluator {
  public:
   explicit GradientProblemEvaluator(const GradientProblem& problem)
       : problem_(problem) {}
 
-
   std::unique_ptr<SparseMatrix> CreateJacobian() const final { return nullptr; }
 
   bool Evaluate(const EvaluateOptions& evaluate_options,
diff --git a/internal/ceres/implicit_schur_complement.h b/internal/ceres/implicit_schur_complement.h
index 83e15fe..598d484 100644
--- a/internal/ceres/implicit_schur_complement.h
+++ b/internal/ceres/implicit_schur_complement.h
@@ -89,7 +89,7 @@
 // RightMultiply (and the LeftMultiply) methods are not thread safe as
 // they depend on mutable arrays used for the temporaries needed to
 // compute the product y += Sx;
-class CERES_NO_EXPORT ImplicitSchurComplement : public LinearOperator {
+class CERES_NO_EXPORT ImplicitSchurComplement final : public LinearOperator {
  public:
   // num_eliminate_blocks is the number of E blocks in the matrix
   // A.
diff --git a/internal/ceres/iterative_schur_complement_solver.h b/internal/ceres/iterative_schur_complement_solver.h
index 674a4ff..0794f36 100644
--- a/internal/ceres/iterative_schur_complement_solver.h
+++ b/internal/ceres/iterative_schur_complement_solver.h
@@ -70,7 +70,7 @@
 // a proof of this fact and others related to this solver please see
 // the section on Domain Decomposition Methods in Saad's book
 // "Iterative Methods for Sparse Linear Systems".
-class CERES_NO_EXPORT IterativeSchurComplementSolver
+class CERES_NO_EXPORT IterativeSchurComplementSolver final
     : public BlockSparseMatrixSolver {
  public:
   explicit IterativeSchurComplementSolver(const LinearSolver::Options& options);
diff --git a/internal/ceres/levenberg_marquardt_strategy.h b/internal/ceres/levenberg_marquardt_strategy.h
index b75c275..4383a49 100644
--- a/internal/ceres/levenberg_marquardt_strategy.h
+++ b/internal/ceres/levenberg_marquardt_strategy.h
@@ -44,7 +44,8 @@
 // K. Madsen, H.B. Nielsen and O. Tingleff. Available to download from
 //
 // http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf
-class CERES_NO_EXPORT LevenbergMarquardtStrategy : public TrustRegionStrategy {
+class CERES_NO_EXPORT LevenbergMarquardtStrategy final
+    : public TrustRegionStrategy {
  public:
   explicit LevenbergMarquardtStrategy(
       const TrustRegionStrategy::Options& options);
diff --git a/internal/ceres/line_search.h b/internal/ceres/line_search.h
index b194fee..c2c744a 100644
--- a/internal/ceres/line_search.h
+++ b/internal/ceres/line_search.h
@@ -259,7 +259,7 @@
 // minFunc package by Mark Schmidt.
 //
 // For more details: http://www.di.ens.fr/~mschmidt/Software/minFunc.html
-class CERES_NO_EXPORT ArmijoLineSearch : public LineSearch {
+class CERES_NO_EXPORT ArmijoLineSearch final : public LineSearch {
  public:
   explicit ArmijoLineSearch(const LineSearch::Options& options);
 
@@ -277,7 +277,7 @@
 //
 // [1] Nocedal J., Wright S., Numerical Optimization, 2nd Ed., Springer, 1999.
 // [2] http://www.di.ens.fr/~mschmidt/Software/minFunc.html.
-class CERES_NO_EXPORT WolfeLineSearch : public LineSearch {
+class CERES_NO_EXPORT WolfeLineSearch final : public LineSearch {
  public:
   explicit WolfeLineSearch(const LineSearch::Options& options);
 
diff --git a/internal/ceres/line_search_direction.cc b/internal/ceres/line_search_direction.cc
index 90ae149..98e335a 100644
--- a/internal/ceres/line_search_direction.cc
+++ b/internal/ceres/line_search_direction.cc
@@ -41,7 +41,7 @@
 namespace ceres {
 namespace internal {
 
-class CERES_NO_EXPORT SteepestDescent : public LineSearchDirection {
+class CERES_NO_EXPORT SteepestDescent final : public LineSearchDirection {
  public:
   bool NextDirection(const LineSearchMinimizer::State& previous,
                      const LineSearchMinimizer::State& current,
@@ -51,7 +51,8 @@
   }
 };
 
-class CERES_NO_EXPORT NonlinearConjugateGradient : public LineSearchDirection {
+class CERES_NO_EXPORT NonlinearConjugateGradient final
+    : public LineSearchDirection {
  public:
   NonlinearConjugateGradient(const NonlinearConjugateGradientType type,
                              const double function_tolerance)
@@ -97,7 +98,7 @@
   const double function_tolerance_;
 };
 
-class CERES_NO_EXPORT LBFGS : public LineSearchDirection {
+class CERES_NO_EXPORT LBFGS final : public LineSearchDirection {
  public:
   LBFGS(const int num_parameters,
         const int max_lbfgs_rank,
@@ -141,7 +142,7 @@
   bool is_positive_definite_;
 };
 
-class CERES_NO_EXPORT BFGS : public LineSearchDirection {
+class CERES_NO_EXPORT BFGS final : public LineSearchDirection {
  public:
   BFGS(const int num_parameters, const bool use_approximate_eigenvalue_scaling)
       : num_parameters_(num_parameters),
diff --git a/internal/ceres/line_search_minimizer.h b/internal/ceres/line_search_minimizer.h
index c5cc9dd..9a0e994 100644
--- a/internal/ceres/line_search_minimizer.h
+++ b/internal/ceres/line_search_minimizer.h
@@ -44,7 +44,7 @@
 // Generic line search minimization algorithm.
 //
 // For example usage, see SolverImpl::Minimize.
-class CERES_NO_EXPORT LineSearchMinimizer : public Minimizer {
+class CERES_NO_EXPORT LineSearchMinimizer final : public Minimizer {
  public:
   struct State {
     State(int num_parameters, int num_effective_parameters)
diff --git a/internal/ceres/line_search_preprocessor.h b/internal/ceres/line_search_preprocessor.h
index 4cb7d68..27e9c2d 100644
--- a/internal/ceres/line_search_preprocessor.h
+++ b/internal/ceres/line_search_preprocessor.h
@@ -38,7 +38,7 @@
 namespace ceres {
 namespace internal {
 
-class CERES_NO_EXPORT LineSearchPreprocessor : public Preprocessor {
+class CERES_NO_EXPORT LineSearchPreprocessor final : public Preprocessor {
  public:
   bool Preprocess(const Solver::Options& options,
                   ProblemImpl* problem,
diff --git a/internal/ceres/low_rank_inverse_hessian.h b/internal/ceres/low_rank_inverse_hessian.h
index 9a74972..3651936 100644
--- a/internal/ceres/low_rank_inverse_hessian.h
+++ b/internal/ceres/low_rank_inverse_hessian.h
@@ -60,7 +60,7 @@
 // Byrd, R. H.; Nocedal, J.; Schnabel, R. B. (1994).
 // "Representations of Quasi-Newton Matrices and their use in
 // Limited Memory Methods". Mathematical Programming 63 (4):
-class CERES_NO_EXPORT LowRankInverseHessian : public LinearOperator {
+class CERES_NO_EXPORT LowRankInverseHessian final : public LinearOperator {
  public:
   // num_parameters is the row/column size of the Hessian.
   // max_num_corrections is the rank of the Hessian approximation.
diff --git a/internal/ceres/manifold_adapter.h b/internal/ceres/manifold_adapter.h
index c612349..552e650 100644
--- a/internal/ceres/manifold_adapter.h
+++ b/internal/ceres/manifold_adapter.h
@@ -9,14 +9,13 @@
 // Adapter to wrap LocalParameterization and make them look like Manifolds.
 //
 // ManifoldAdapter NEVER takes ownership of local_parameterization.
-class CERES_NO_EXPORT ManifoldAdapter : public Manifold {
+class CERES_NO_EXPORT ManifoldAdapter final : public Manifold {
  public:
   ManifoldAdapter(const LocalParameterization* local_parameterization)
       : local_parameterization_(local_parameterization) {
     CHECK(local_parameterization != nullptr);
   }
 
-
   bool Plus(const double* x,
             const double* delta,
             double* x_plus_delta) const override {
diff --git a/internal/ceres/partitioned_matrix_view.h b/internal/ceres/partitioned_matrix_view.h
index dc2ef18..9eaec6f 100644
--- a/internal/ceres/partitioned_matrix_view.h
+++ b/internal/ceres/partitioned_matrix_view.h
@@ -117,7 +117,8 @@
 template <int kRowBlockSize = Eigen::Dynamic,
           int kEBlockSize = Eigen::Dynamic,
           int kFBlockSize = Eigen::Dynamic>
-class CERES_NO_EXPORT PartitionedMatrixView : public PartitionedMatrixViewBase {
+class CERES_NO_EXPORT PartitionedMatrixView final
+    : public PartitionedMatrixViewBase {
  public:
   // matrix = [E F], where the matrix E contains the first
   // num_col_blocks_a column blocks.
diff --git a/internal/ceres/preconditioner.h b/internal/ceres/preconditioner.h
index d309e4f..7e63147 100644
--- a/internal/ceres/preconditioner.h
+++ b/internal/ceres/preconditioner.h
@@ -167,7 +167,7 @@
 // clang-format on
 
 // Wrap a SparseMatrix object as a preconditioner.
-class CERES_NO_EXPORT SparseMatrixPreconditionerWrapper
+class CERES_NO_EXPORT SparseMatrixPreconditionerWrapper final
     : public SparseMatrixPreconditioner {
  public:
   // Wrapper does NOT take ownership of the matrix pointer.
diff --git a/internal/ceres/program_evaluator.h b/internal/ceres/program_evaluator.h
index e0f7bf0..826a73a 100644
--- a/internal/ceres/program_evaluator.h
+++ b/internal/ceres/program_evaluator.h
@@ -111,7 +111,7 @@
 template <typename EvaluatePreparer,
           typename JacobianWriter,
           typename JacobianFinalizer = NullJacobianFinalizer>
-class ProgramEvaluator : public Evaluator {
+class ProgramEvaluator final : public Evaluator {
  public:
   ProgramEvaluator(const Evaluator::Options& options, Program* program)
       : options_(options),
diff --git a/internal/ceres/schur_complement_solver.cc b/internal/ceres/schur_complement_solver.cc
index adc1531..3f8cfea 100644
--- a/internal/ceres/schur_complement_solver.cc
+++ b/internal/ceres/schur_complement_solver.cc
@@ -62,13 +62,12 @@
 
 namespace {
 
-class BlockRandomAccessSparseMatrixAdapter : public LinearOperator {
+class BlockRandomAccessSparseMatrixAdapter final : public LinearOperator {
  public:
   explicit BlockRandomAccessSparseMatrixAdapter(
       const BlockRandomAccessSparseMatrix& m)
       : m_(m) {}
 
-
   // y = y + Ax;
   void RightMultiply(const double* x, double* y) const final {
     m_.SymmetricRightMultiply(x, y);
@@ -86,13 +85,12 @@
   const BlockRandomAccessSparseMatrix& m_;
 };
 
-class BlockRandomAccessDiagonalMatrixAdapter : public LinearOperator {
+class BlockRandomAccessDiagonalMatrixAdapter final : public LinearOperator {
  public:
   explicit BlockRandomAccessDiagonalMatrixAdapter(
       const BlockRandomAccessDiagonalMatrix& m)
       : m_(m) {}
 
-
   // y = y + Ax;
   void RightMultiply(const double* x, double* y) const final {
     m_.RightMultiply(x, y);
diff --git a/internal/ceres/schur_complement_solver.h b/internal/ceres/schur_complement_solver.h
index 0f9e011..1ea9ad4 100644
--- a/internal/ceres/schur_complement_solver.h
+++ b/internal/ceres/schur_complement_solver.h
@@ -148,7 +148,7 @@
 };
 
 // Dense Cholesky factorization based solver.
-class CERES_NO_EXPORT DenseSchurComplementSolver
+class CERES_NO_EXPORT DenseSchurComplementSolver final
     : public SchurComplementSolver {
  public:
   explicit DenseSchurComplementSolver(const LinearSolver::Options& options);
@@ -167,7 +167,7 @@
 };
 
 // Sparse Cholesky factorization based solver.
-class CERES_NO_EXPORT SparseSchurComplementSolver
+class CERES_NO_EXPORT SparseSchurComplementSolver final
     : public SchurComplementSolver {
  public:
   explicit SparseSchurComplementSolver(const LinearSolver::Options& options);
diff --git a/internal/ceres/schur_eliminator.h b/internal/ceres/schur_eliminator.h
index e03d2d9..f77acbd 100644
--- a/internal/ceres/schur_eliminator.h
+++ b/internal/ceres/schur_eliminator.h
@@ -224,7 +224,7 @@
 template <int kRowBlockSize = Eigen::Dynamic,
           int kEBlockSize = Eigen::Dynamic,
           int kFBlockSize = Eigen::Dynamic>
-class CERES_NO_EXPORT SchurEliminator : public SchurEliminatorBase {
+class CERES_NO_EXPORT SchurEliminator final : public SchurEliminatorBase {
  public:
   explicit SchurEliminator(const LinearSolver::Options& options)
       : num_threads_(options.num_threads), context_(options.context) {
@@ -379,7 +379,8 @@
 template <int kRowBlockSize = Eigen::Dynamic,
           int kEBlockSize = Eigen::Dynamic,
           int kFBlockSize = Eigen::Dynamic>
-class CERES_NO_EXPORT SchurEliminatorForOneFBlock : public SchurEliminatorBase {
+class CERES_NO_EXPORT SchurEliminatorForOneFBlock final
+    : public SchurEliminatorBase {
  public:
   void Init(int num_eliminate_blocks,
             bool assume_full_rank_ete,
diff --git a/internal/ceres/sparse_cholesky.h b/internal/ceres/sparse_cholesky.h
index 25249eb..80c5cb2 100644
--- a/internal/ceres/sparse_cholesky.h
+++ b/internal/ceres/sparse_cholesky.h
@@ -116,7 +116,7 @@
 
 // Computes an initial solution using the given instance of
 // SparseCholesky, and then refines it using the IterativeRefiner.
-class CERES_NO_EXPORT RefinedSparseCholesky : public SparseCholesky {
+class CERES_NO_EXPORT RefinedSparseCholesky final : public SparseCholesky {
  public:
   RefinedSparseCholesky(std::unique_ptr<SparseCholesky> sparse_cholesky,
                         std::unique_ptr<IterativeRefiner> iterative_refiner);
diff --git a/internal/ceres/suitesparse.h b/internal/ceres/suitesparse.h
index 604c7fc..60b415c 100644
--- a/internal/ceres/suitesparse.h
+++ b/internal/ceres/suitesparse.h
@@ -291,7 +291,7 @@
   cholmod_common cc_;
 };
 
-class CERES_NO_EXPORT SuiteSparseCholesky : public SparseCholesky {
+class CERES_NO_EXPORT SuiteSparseCholesky final : public SparseCholesky {
  public:
   static std::unique_ptr<SparseCholesky> Create(OrderingType ordering_type);
 
diff --git a/internal/ceres/triplet_sparse_matrix.h b/internal/ceres/triplet_sparse_matrix.h
index 2c2bc13..bcb4529 100644
--- a/internal/ceres/triplet_sparse_matrix.h
+++ b/internal/ceres/triplet_sparse_matrix.h
@@ -47,7 +47,7 @@
 // manipulate sparse matrices in triplet (i,j,s) form.  This object is
 // inspired by the design of the cholmod_triplet struct used in the
 // SuiteSparse package and is memory layout compatible with it.
-class CERES_NO_EXPORT TripletSparseMatrix : public SparseMatrix {
+class CERES_NO_EXPORT TripletSparseMatrix final : public SparseMatrix {
  public:
   TripletSparseMatrix();
   TripletSparseMatrix(int num_rows, int num_cols, int max_num_nonzeros);
diff --git a/internal/ceres/trust_region_minimizer.h b/internal/ceres/trust_region_minimizer.h
index 4df0510..c6fc542 100644
--- a/internal/ceres/trust_region_minimizer.h
+++ b/internal/ceres/trust_region_minimizer.h
@@ -49,7 +49,7 @@
 // Generic trust region minimization algorithm.
 //
 // For example usage, see SolverImpl::Minimize.
-class CERES_NO_EXPORT TrustRegionMinimizer : public Minimizer {
+class CERES_NO_EXPORT TrustRegionMinimizer final : public Minimizer {
  public:
   // This method is not thread safe.
   void Minimize(const Minimizer::Options& options,
diff --git a/internal/ceres/trust_region_preprocessor.h b/internal/ceres/trust_region_preprocessor.h
index a1db8e8..26ef8fa 100644
--- a/internal/ceres/trust_region_preprocessor.h
+++ b/internal/ceres/trust_region_preprocessor.h
@@ -38,7 +38,7 @@
 namespace ceres {
 namespace internal {
 
-class CERES_NO_EXPORT TrustRegionPreprocessor : public Preprocessor {
+class CERES_NO_EXPORT TrustRegionPreprocessor final : public Preprocessor {
  public:
   bool Preprocess(const Solver::Options& options,
                   ProblemImpl* problem,