Когда сделать класс final [duplicate]

Вы хотите, чтобы более низкая частота повышалась так:

  public int compare(TreeNodeHuffman p1, TreeNodeHuffman p2) {
          if (p1.frequency < p2.frequency) return 1;
          if (p1.frequency > p2.frequency) return -1;
          return 0;
      }    
   }

Если вы хотите протестировать ее, отправьте ее в один пул с потоком и посмотрите порядок обрабатываемых заданий вместо строки или итератора , как говорит doc в http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html#iterator%28%29 :

Возвращает итератор по элементам в этой очереди. Итератор не возвращает элементы в каком-либо конкретном порядке.

Можно увидеть http://docs.oracle.com/javase/7/docs/api/java/util/ concurrent / Executors.html # newSingleThreadExecutor% 28% 29 для быстрого однопоточного пула, чтобы проверить это.

20
задан BЈовић 29 May 2013 в 09:48
поделиться

2 ответа

Один интересный необычный случай использования, который я нашел, я описал здесь здесь . Короче говоря, предотвращая наследование от вашего класса типа int, вы покупаете себе возможность заменить его встроенным типом в будущих версиях вашей библиотеки, не рискуя нарушить код пользователя.

Но более распространенным примером является девиртуализация . Если вы отметите свой класс как final, компилятор может применить определенные оптимизации во время выполнения. Например,

struct Object {
  virtual void run() = 0;
  virtual ~Object() {}
};

struct Impl final : Object
{
  void run() override {}
};

void fun(Impl & i)
{
  i.run(); // inlined!
}

Вызов i.run() может быть теперь встроен из-за спецификатора final. Компилятор знает, что vtable look-up не понадобится.

8
ответ дан Andrzej 18 August 2018 в 18:57
поделиться
  • 1
    Ну, я собирался сказать, что вышеупомянутая ссылка уже была распространена в комментариях, но я не понимал, что это тоже твоя собственная статья. – Morwenn 10 December 2013 в 15:40

final может быть полезна, когда вы предоставляете (вид) фасад первоначальному интерфейсу, который проще использовать подклассами. Рассмотрим:

class IMovable {
  public:
    void GoTo(unsigned position) = 0;
}

class Stepper : public IMovable {
  public:
    void GoTo(unsigned position) final;
  protected:
    virtual void MoveLeft() = 0;
    virtual void MoveRight() = 0;
}

void Stepper::GoTo(unsigned position) {
  for(;current_pos < position; current_pos++) {
     MoveRight(); 
  }
  for(;current_pos > position; current_pos--) {
     MoveLeft();
  } 
}       

Теперь, если вы хотите получить Stepper, вы увидите, что вы должны переопределить MoveRight и MoveLeft, но вы не должны переопределять GoTo.

Это очевидно на этом маленьком примере, но если IMovable имеет 20 методов, а у Stepper 25, и были реализации по умолчанию, чем вам может быть трудно выяснить, что вы должны и что вы должны " t переопределить. Я встречал такую ​​ситуацию в библиотеке, связанной с оборудованием. Но я бы не назвал это серьезной проблемой, заслуживающей внимания стандартом;)

0
ответ дан Steed 18 August 2018 в 18:57
поделиться
  • 1
    это не объявление финал class! – Alex 10 December 2013 в 14:49
  • 2
    @Алекс, ты прав. Мое внимание привлекло фразу о виртуальных функциях, поэтому я пропустил акцент на том, чтобы сделать класс окончательным, а не функции. Дорогой ОП, следует ли мне отменить ответ или вас тоже интересуют конечные функции? – Steed 10 December 2013 в 14:56
  • 3
    @Steed Мне очень жаль, но меня вообще не интересуют функции final; Я уже знал, почему они существуют, даже перед тем, как задать вопрос ^^ & quot; – Morwenn 10 December 2013 в 15:36
Другие вопросы по тегам:

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