const_cast в шаблоне. Существует ли unconst модификатор?

В Java 7 Вы не должны закрывать их явно, но использование автоматическое управление ресурсами , чтобы гарантировать, что ресурсы закрываются, и исключения обработаны соответственно. Обработка исключений работает как это:

Exception in try | Exception in close | Result
-----------------+--------------------+----------------------------------------
      No         |        No          | Continue normally
      No         |        Yes         | Throw the close() exception
      Yes        |        No          | Throw the exception from try block
      Yes        |        Yes         | Add close() exception to main exception
                 |                    |  as "suppressed", throw main exception

, Надо надеяться, который имеет смысл. В позволяет симпатичный код, как это:

private void doEverythingInOneSillyMethod(String key)
  throws MyAppException
{
  try (Connection db = ds.getConnection()) {
    db.setReadOnly(true);
    ...
    try (PreparedStatement ps = db.prepareStatement(...)) {
      ps.setString(1, key);
      ...
      try (ResultSet rs = ps.executeQuery()) {
        ...
      }
    }
  } catch (SQLException ex) {
    throw new MyAppException("Query failed.", ex);
  }
}

До Java 7, лучше использовать вложенный наконец блоки, вместо того, чтобы тестировать ссылки на пустой указатель.

пример, который я покажу, мог бы выглядеть ужасным с глубоким вложением, но на практике, хорошо разработанный код, вероятно, не собирается создавать соединение, оператор и результаты все в том же методе; часто, каждый уровень вложения включает передачу ресурса к другому методу, который использует его в качестве фабрики для другого ресурса. С этим подходом исключения из close() замаскируют исключение изнутри try блок. Это может быть преодолено, но это приводит к еще более грязному коду и требует пользовательского класса исключений, который обеспечивает "подавленное" объединение в цепочку исключения, существующее в Java 7.

Connection db = ds.getConnection();
try {
  PreparedStatement ps = ...;
  try {
    ResultSet rs = ...
    try {
      ...
    }
    finally {
      rs.close();
    }
  } 
  finally {
    ps.close();
  }
} 
finally {
  db.close();
}

5
задан danatel 4 October 2009 в 14:39
поделиться

4 ответа

Самый простой способ - сделать счетчик ссылок изменяемым.

Однако, если вас интересует, как он будет работать с const_cast , тогда переопределите boost remove_const должно быть довольно простым:

template <class T>
struct RemoveConst
{
    typedef T type;
};

template <class T>
struct RemoveConst<const T>
{
    typedef T type;
};

const_cast<typename RemoveConst<T>::type*>(t)->inc();
12
ответ дан 18 December 2019 в 06:35
поделиться

У вас есть ответ. const_cast работает в обоих направлениях:

char* a;
const char* b;

a = const_cast<char*>(b);
b = const_cast<const char*>(a); // not strictly necessarily, just here for illustration

Что касается конкретной проблемы, рассматривали ли вы ключевое слово mutable? Он позволяет изменять переменную-член внутри метода const.

class foo {
    mutable int x;
public:
    inc_when_const() const { ++x; }
    dec_when_const() const { --x; }
};
5
ответ дан 18 December 2019 в 06:35
поделиться

Сделайте счетчик ссылок изменяемым в классе, управляемом вашим навязчивым указателем. Это вполне разумно и точно отражает «логическую константность» - то есть изменение счетчика ссылок на объект не отражает никаких изменений в состоянии самого объекта. Другими словами, счетчик ссылок логически не является частью объекта - объект просто оказывается удобным местом для хранения этих полунезависимых данных.

4
ответ дан 18 December 2019 в 06:35
поделиться

Если вы можете использовать Boost, библиотека Type Traits предоставляет метафункцию remove_const , которая делает это.

3
ответ дан 18 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: