A class designed to be inherited-from is called a Base class. Care should be taken with the special member functions of such a class.
A class designed to be used polymorphically at run-time (through a pointer to the base class) should declare the destructor virtual. This allows the derived parts of the object to be properly destroyed, even when the object is destroyed through a pointer to the base class.
class Base {
public:
    virtual ~Base() = default;
private:
    //    data members etc.
};
class Derived : public Base { //  models Is-A relationship
public:
    //    some methods
private:
    //    more data members
};
//    virtual destructor in Base ensures that derived destructors
//    are also called when the object is destroyed
std::unique_ptr<Base> base = std::make_unique<Derived>();
base = nullptr;  //    safe, doesn't leak Derived's members
If the class does not need to be polymorphic, but still needs to allow its interface to be inherited, use a non-virtual protected destructor.
class NonPolymorphicBase {
public:
    //    some methods
protected:
    ~NonPolymorphicBase() = default; //    note: non-virtual
private:
    //    etc.
};
Such a class can never be destroyed through a pointer, avoiding silent leaks due to slicing.
This technique especially applies to classes designed to be private base classes. Such a class might be used to encapsulate some common implementation details, while providing virtual methods as customisation points. This kind of class should never be used polymorphically, and a protected destructor helps to document this requirement directly in the code.
Finally, some classes may require that they are never used as a base class. In this case, the class can be marked final. A normal non-virtual public destructor is fine in this case.
class FinalClass final {  //    marked final here
public:
    ~FinalClass() = default;
private:
    //    etc.
};