В большинстве случаев использование защищенного опасно, поскольку вы несколько нарушаете инкапсуляцию вашего класса, которая может быть нарушена плохо разработанным производным классом.
Но у меня есть один хороший пример: допустим, вы можете использовать какой-то универсальный контейнер. Он имеет внутреннюю реализацию и внутренние средства доступа. Но вам нужно предложить как минимум 3 открытых доступа к своим данным: map, hash_map, vector-like. Тогда у вас есть что-то вроде:
template <typename T, typename TContainer>
class Base
{
// etc.
protected
TContainer container ;
}
template <typename Key, typename T>
class DerivedMap : public Base<T, std::map<Key, T> > { /* etc. */ }
template <typename Key, typename T>
class DerivedHashMap : public Base<T, std::hash_map<Key, T> > { /* etc. */ }
template <typename T>
class DerivedVector : public Base<T, std::vector<T> > { /* etc. */ }
Я использовал этот вид кода менее месяца назад (поэтому код из памяти). Подумав немного, я считаю, что хотя базовый контейнер Base должен быть абстрактным классом, даже если он может жить довольно хорошо, потому что непосредственное использование Base было бы такой болью, его следует запретить.
Сводка Таким образом, вы защитили данные, используемые производным классом. Тем не менее, мы должны принять во внимание тот факт, что базовый класс должен быть абстрактным.