Разница в синтаксисе для передачи значений в конструктор c ++ - PullRequest
0 голосов
/ 14 сентября 2018

здесь я использую два синтаксиса для передачи значений в конструктор: -

class A   
{

public:
    int x,y;

    A(int a,int b) : x(a),y(b){}
    void show()
    {
        cout<<x<<" "<<y<<endl;
    }
};

int main()
{

    A obj1={5,6};//first method
    A obj2(9,10);//second method

    obj1.show();
    obj2.show();
}

И оба работают нормально но когда я удаляю саму функцию конструктора, то и первый метод работает нормально. пожалуйста, объясните это.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Когда вы удаляете этот конструктор, class A получает право на совокупную инициализацию , что вызвано здесь этим фигурными скобками синтаксис: A obj1={5,6}; (он также имеет такую ​​эквивалентную форму: A obj1{5,6}; начиная с C ++ 11)

Поскольку вы можете прочитать здесь , это применимо в вашем случае, так как class A не имеет ничего из следующего:

  1. частные или защищенные нестатические члены данных (применяется до C ++ 11)
  2. конструкторы, объявленные пользователем (применяются с C ++ 11 до C ++ 17)
  3. предоставленные пользователем конструкторы (допускаются явно заданные по умолчанию или удаленные конструкторы) (применяется с C ++ 17 до C ++ 20)
  4. предоставленные пользователем, унаследованные или явные конструкторы (явно установленные по умолчанию или удаленныеконструкторы допускаются) (применяется с C ++ 20)
  5. объявленные пользователем или унаследованные конструкторы
  6. виртуальные, частные или защищенные (применяется с C ++ 17) базовые классы
  7. виртуальные функции-члены
  8. инициализаторы-члены по умолчанию(применяется с C ++ 11 до C ++ 14)

Напротив, этот синтаксис: A obj2(9,10); выполняет прямую инициализацию и он не скомпилируется после удаления конструктора из-за [dcl.init¶17.6.2] :

[...], если инициализация прямая инициализация [...] рассматриваются конструкторы.[...] Если ни один конструктор не применяет [...], инициализация некорректна.


До удаления конструктора тот же синтаксис A obj1={5,6}; вызывал его при выполнении copy-list-initialization .


Что такое совокупная инициализация ?Это инициализация экземпляра агрегатного типа (либо массива, либо структуры / класса, соответствующего приведенному выше списку) с помощью braced-init-list синтаксис.Аргументы внутри фигурных скобок должны совпадать с нестатическими элементами данных struct / class в порядке объявления .В более поздних версиях C ++ он получил значительный импульс, поскольку в язык были добавлены более синтаксические формы для него.Ваше использование ={...} является единственным существовавшим до C ++ 11.


Общие плюсы и минусы использования скобочных форм инициализации по сравнению с фигурной инициализацией обсуждаются многими.Хорошее место, чтобы получить исчерпывающую информацию - пункт 7 Скотта Мейерса Effective Modern C ++ .При этом главное преимущество всех форм инициализации фигурных скобок заключается в том, что они не допускают сужение .

0 голосов
/ 14 сентября 2018
A obj1={5,6};

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

Это может помочь вам понять: Почему инициализация списка (с использованием фигурных скобок) лучше, чем альтернативы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...