Design for class which accepts large array in constructor
Don't pass arrays as pointers ...

... for multiple reasons. Your current design


always copies the arrays x, y deeply
can be misused by passing nullptr and trusts the user that length is chosen correctly.


Instead of 

interpolator(const Real* const x, const Real* const y, size_t length) {  /* ... */ }


use

interpolator(std::vector&lt;Real&gt; x, std::vector&lt;Real&gt; y)
: m_x{std::move(x)}
, m_y{std::move(y)}
{ if (m_x.size() != m_y.size()) throw std::logic_error{"NO!"}; }


or if the memory layout doesn't effect the performance too much

interpolate(std::vector&lt;std::array&lt;Real, 2&gt;&gt; xy): m_xy{std::move(xy)} {}


If you want to initialise your data from any range use templates and constrain its type to guard for errors at compile time.

Prefer regular functions for computations

This means, that an implemented function is also a function in the mathematical sense. Same input data produces same output data. I found that this almost always leads to evaluations which do not change an inner state. Thus it smells to me that

Real interpolate_at(Real);


is not

Real interpolate_at(Real) const;