Не разрешайте использование конструктора по умолчанию в C ++

Я пытаюсь создать класс на C ++, который запрещает использование конструктора по умолчанию.
Тем не менее, я думаю, что у меня не получается, или я не понимаю, что происходит за кулисами . Вот что у меня есть на данный момент:

class Point {
public:
        float x;
        float y;
        Point(float newX, float newY); //Definition is irrelevant
        Point() = delete; //Default or "empty" constructor is forbidden, so deleted
}
/* ... */
int main(void)
{
        Point a(1, 2); //Ok, should be available
        Point b; //Ok, does not compile
        Point c(); //Not ok, it does compile :(
}

Я предполагаю, что пункт c не компилируется. Я был бы признателен за помощь в создании такого поведения или, если это невозможно, за объяснение того, почему это так работает.

заранее спасибо


person Manuel W.    schedule 01.12.2017    source источник
comment
Я получил ответ в этой предыдущей теме: stackoverflow.com/questions/40683637/. Обратите внимание, что опубликованный код в вопросе был обновлен, чтобы показать, как это сделать.   -  person rcgldr    schedule 01.12.2017
comment
c не является объектом. Так что c'tor по умолчанию не вызывается, не волнуйтесь.   -  person StoryTeller - Unslander Monica    schedule 01.12.2017


Ответы (3)


Происходит досадный разбор. Вы объявляете не объект, а функцию с именем c и возвращаемым типом класса Point.


Объявление любого конструктора не позволит компилятору сгенерировать конструктор по умолчанию, поэтому объявление с =delete - это суперпотоки.


Агрегированная инициализация

Если вы знаете порядок, вам даже не нужен конструктор:

Point p{newX, newY};

Будет работать нормально.


Единый синтаксис инициализации

В дальнейшем, чтобы избежать таких случаев, используйте {}:

Point p{}; //default constructs
person Incomputable    schedule 01.12.2017

Линия

    Point c(); //Not ok, it does compile :(

Не интерпретируется как создание объекта c типа Point, он интерпретируется как объявление новой функции c, которая возвращает Point и не принимает аргументов. Посмотрите здесь: https://en.wikipedia.org/wiki/Most_vexing_parse

В этой строке также нет необходимости:

    Point() = delete; //Default or "empty" constructor is forbidden, so deleted

Если вы объявляете какой-либо конструктор, то конструктор по умолчанию перезаписывается.

person idontseethepoint    schedule 01.12.2017

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

struct Foo {
    Foo(int);
}

Foo x; // wont compile

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

Почему он компилировался?

Foo x();

объявляет функцию, возвращающую Foo. Это самый неприятный разбор.

person 463035818_is_not_a_number    schedule 01.12.2017