Использование const_cast в фабричной модели

Простите/поправьте меня, если моя номенклатура неверна.

Я никогда не понимал использование const_cast. Вообще говоря, мне кажется, что если вы должны использовать const_cast, то ваш класс/методы, вероятно, в корне ошибочны если только вы не используете устаревшие функции, не являющиеся константно-корректными. Однако я, возможно, наткнулся на случай, когда его использование уместно. У меня есть большой класс с парой членов, которые назначаются во время создания и остаются постоянными в течение полезного срока службы объекта.

Поскольку эти объекты часто уничтожаются и создаются, я хотел бы поэкспериментировать с тем, что, как мне кажется, называется фабричной моделью: вместо создания/уничтожения объекта я хотел бы получить/вернуть его в кэш неназначенных объектов. Например (упрощенно, конечно):

class PersonFactory {
public:
    const Person* getPerson(const QString& newname) {
    //I can't assign the new name because it's const
        if(m_personCache.isEmpty())
            return createNewPerson();
        else
            return m_personCache.pop();
    }
    void returnPerson(Person* person) { m_personCache.push(person); person = 0; }
    static PersonFactory* instance;
private:
    Person* createNewPerson() const { return new Person(""); }
    QStack<Person*> m_personCache;
}

class Person {
public:
    friend Person* PersonFactory::createNewPerson();

    const QString& name() const {
        return m_name;
    }

    void destroy() {
        PersonFactory::returnPerson(this);
    }
private:
    Person(QString name) : m_name(name) {}
    //m_name is const and should remain that way to prevent accidental changes
    const QString m_name;
}

Я не могу назначить новое имя, потому что это const. Это хороший случай для const_cast или я упустил очевидную альтернативу? Приведет ли использование const_cast к снижению производительности?


person Phlucious    schedule 13.12.2012    source источник
comment
mutable не является признаком дефекта конструкции. Это сделано для того, чтобы объекты могли, например, кэшировать значения вместо того, чтобы пересчитывать их каждый раз, когда они нужны.   -  person Pete Becker    schedule 14.12.2012
comment
Я удалил ссылку на mutable, так как она ничего не добавила в вопрос. Конечно, бывают случаи, когда его использование необходимо.   -  person Phlucious    schedule 14.12.2012
comment
вместо того, чтобы возиться с шаблонами проектирования Java, рассмотрите возможность использования распределителя небольших объектов C++, такого как тот, что есть в библиотеке Loki. например, с подходом Java вы не можете использовать значения по умолчанию для std::unique_ptr и std::shared_ptr. таким образом, это оказывает негативное влияние на правильность и объем работы   -  person Cheers and hth. - Alf    schedule 14.12.2012


Ответы (1)


Приведет ли использование const_cast к снижению производительности?

Может быть. Отбрасывание const для сохранения значения, когда объект на самом деле является const, приводит к неопределенному поведению. Неопределенное поведение может проявляться, среди прочего, как снижение производительности.

person Pete Becker    schedule 13.12.2012
comment
Отбрасывание const для сохранения значения, когда объект на самом деле является const, приводит к неопределенному поведению. Можете ли вы уточнить, что вы подразумеваете под неопределенным поведением? - person Phlucious; 14.12.2012
comment
Я имею в виду, что определение языка не накладывает никаких требований на то, что делает реализация. Простой пример, с которым сталкиваются многие новички: int main() { const int i = 3; const_cast<int&>(i) = 4; std::cout << i << '\n'; return 0; } и они удивлены тем, что программа выводит 3. Что касается неопределенного поведения, это довольно безобидно. - person Pete Becker; 14.12.2012
comment
Понял. Таким образом, использование фабричного шаблона в том виде, в котором он реализован, сводит на нет возможность для m_name оставаться const QString? Я полагаю, я мог бы сделать его не-const, сделать PersonFactory friend class, а затем назначить его напрямую. Это правильная техника ООП? - person Phlucious; 14.12.2012
comment
Неважно. Эта ссылка, кажется, ясно отвечает на этот вопрос. Этот вариант использования const_cast кажется в корне неверным. Спасибо! - person Phlucious; 14.12.2012