Достаточно ли удаления копий и перемещения конструкторов / операторов присваивания в базовом классе?

Когда в выражении лямбда используется назначенная локальная переменная из ее вмещающего пространства, существует важное ограничение. В выражении лямбда может использоваться только локальная переменная, значение которой не изменяется. Это ограничение упоминается как «захват переменной», который описывается как; значения захвата выражения лямбда, а не переменные . Локальные переменные, которые могут использовать выражение лямбда, известны как «эффективно окончательные». Эффективно конечная переменная - это значение, значение которого не изменяется после его первого назначения. Нет необходимости явно объявлять такую ​​переменную как final, хотя делать это не будет ошибкой. Давайте посмотрим на пример, у нас есть локальная переменная i, которая инициализируется значением 7, причем в выражении лямбда мы пытаемся изменить это значение, назначив новое значение i. Это приведет к ошибке компилятора - « Локальная переменная i, определенная в охватывающей области, должна быть окончательной или эффективной окончательной "

@FunctionalInterface
interface IFuncInt {
    int func(int num1, int num2);
    public String toString();
}

public class LambdaVarDemo {

    public static void main(String[] args){             
        int i = 7;
        IFuncInt funcInt = (num1, num2) -> {
            i = num1 + num2;
            return i;
        };
    }   
}
2
задан Mike Sweeney 5 March 2019 в 16:36
поделиться

2 ответа

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

Но производный класс может явно построить свою базу с помощью ctor по умолчанию:

class DerivedClass : public BaseClass {
public:
  DerivedClass();
  DerivedClass(const DerivedClass &): BaseClass() {
      // copy ctor for the derived part
  }
  bool doSomething() override;
};

Et voila ... класс DerivedClass теперь копируемый, несмотря на то, что его базовый класс - нет!

0
ответ дан Serge Ballesta 5 March 2019 в 16:36
поделиться

Вы не можете запретить дочернему классу определять собственный конструктор копирования / перемещения. Тем не менее, это предотвратит его «из коробки», то есть если вы его не предоставите или используете встроенный конструктор по умолчанию, он также будет помечен как удаленный. Причина, по которой вы получаете ошибку здесь, когда вы пытаетесь просто определить конструктор по умолчанию, заключается в том, что вам не разрешено делать это во внешнем определении, когда член или база неявно удалили его. Если бы вы использовали

class DerivedClass : public BaseClass {
public:
  DerivedClass(const DerivedClass &) = default;
  bool doSomething() override;
};

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

0
ответ дан NathanOliver 5 March 2019 в 16:36
поделиться
Другие вопросы по тегам:

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