• Что такое «необъявленный интерфейс» вашего нового типа? Какого рода гарантии могут быть предоставлены относительно производительности, безопасности относительно исключений (см. правило 29) и использования ресурсов (например, блокировок и динамической памяти)? Такого рода гарантии определяют ограничения на реализацию вашего класса.
• Насколько общий ваш новый тип? Возможно, в действительности вы не определяете новый тип. Возможно, вы определяете целое
• Действительно ли новый тип представляет собой то, что вам нужно? Если вы определяете новый производный класс только для того, чтобы расширить функциональность существующего класса, то, возможно, этой цели лучше достичь простым определением одной или более функций-нечленов либо шаблонов.
На эти вопросы нелегко ответить, поэтому определение эффективных классов – непростая задача. Но при ее должном выполнении определенные пользователями классы C++ дают типы, которые ничем не уступают встроенным и уже оправдывают все ваши усилия.
Что следует помнить
• Проектирование класса – это проектирование типа. Прежде чем определять новый тип, убедитесь, что рассмотрены все вопросы, которые обсуждаются в настоящем правиле.
Правило 20: Предпочитайте передачу по ссылке на const передаче по значению
По умолчанию в C++ объекты передаются в функции и возвращаются функциями по значению (свойство, унаследованное от C). Если не указано противное, параметры функции инициализируются копиями реальных аргументов, а после вызова функции программа получает
class Person {
public:
Person(); // параметры опущены для простоты
virtual ~Person(); // см. в правиле 7 – почему виртуальный
…
private:
std::string name;
std::string address;
};
class Student: public Person {
public:
Student(); // и здесь параметры опущены
~ Student();
…
private:
std::string schoolName;
std::string schoolAddress;
};Теперь взгляните на следующий код, где вызывается функция validateStudent, которая принимает аргумент Student (по значению) и возвращает признак его корректности:
bool validateStudent(Student s); // функция принимает параметр
// Student по значению
Student plato; // Платон учился у Сократа
bool platoIsOk = validateStudent(plato); // вызов функции