Аргумент по умолчанию с использованием фигурных скобок инициализатора
У меня есть этот фрагмент кода, который, кажется, работает хорошо:
class foo{/* some member variables and functions*/};
void do_somthing(foo x={}){}
int main(){
do_somthing();
}
Я использовал, чтобы использовать void do_somthing(foo x=foo()){}
по умолчанию x
аргумент, но я вижу этот путь ={}
в какой-то книге или онлайн-примере (не помню). Это полностью нормально использовать? Есть ли разница между этими двумя методами?
1 ответ
foo x=foo()
инициализация копии,
Инициализирует объект из другого объекта
а также foo()
это инициализация значения.
Это инициализация, выполняемая, когда переменная создается с пустым инициализатором.
foo x={}
это агрегатная инициализация.
Инициализирует агрегат из списка braced-init-list
Если количество предложений инициализатора меньше количества членов и баз (начиная с C++17) или список инициализаторов полностью пуст, остальные члены и базы (начиная с C++17) инициализируются инициализаторами по умолчанию, если они предоставляются в определении класса, и в противном случае (начиная с C++14) пустыми списками, которые выполняют инициализацию значения.
Таким образом, результат в этом случае одинаков (оба значения инициализированы).
И последствия инициализации значения в этом случае:
если T является типом класса с конструктором по умолчанию, который не предоставлен и не удален пользователем (то есть это может быть класс с неявно определенным или дефолтным конструктором по умолчанию), объект инициализируется нулями
Наконец, эффекты нулевой инициализации в этом случае:
Если T является скалярным типом, начальное значение объекта является целочисленной константой ноль, явно преобразованной в T.
Если T является типом класса, не являющимся объединением, все базовые классы и нестатические члены данных инициализируются нулями, а все заполнение инициализируется нулевыми битами. Конструкторы, если таковые имеются, игнорируются.