конструкторы в C ++ - PullRequest
       53

конструкторы в C ++

6 голосов
/ 12 апреля 2010

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

Ответы [ 10 ]

10 голосов
/ 12 апреля 2010

По мнению Страуструпа, потому что альтернатива новой функции «была источником путаницы».См. «Разработка и развитие C ++», раздел 3.11.2, хотя это полное оправдание, которое я цитировал.

Редактировать: Как указывали люди, существует ряд альтернативных решений.Например, Smalltalk делает это:

myclass new

отправка «нового» сообщения в объект класса myclass.Очевидно, что решение C ++ здесь было бы немного глупо:

myclass myclass

явно не имеет смысла.

Delphi, OTOH, позволяет любой именованной функции быть конструктором, пометив ее так:

constructor Create;
constructor FooBar;

будут именами конструкторов OK для любого класса.Как и в случае с Smalltalk, вам нужно вызвать их для объекта класса:

myclass.Create;

Из всех этих решений я считаю C ++ одним из самых элегантных, и я понимаю, почему он был почти повсеместно принятязыки-преемники.

9 голосов
/ 12 апреля 2010

Стандарт языка C ++:

12,1. Конструкторы не имеют имен.

Ваш вопрос основан на путанице. Конструкторы используют специальный синтаксис объявления, где вместо имени члена снова используется имя класса. Я не вижу ничего плохого в этом синтаксисе, поэтому я даже не представляю, что может вызвать ваш вопрос (что затрудняет, если не делает невозможным ответ).

Тем не менее, конструкторы в C ++ не имеют имен. Им просто не нужны имена, потому что в C ++ нет контекста, в котором вы должны ссылаться на конструктор.

5 голосов
/ 12 апреля 2010

В оригинальном «C с классами» его фактически не было - его называли «новым», IIRC. В любом случае, на большинство вопросов «почему» о C ++ вы можете найти ответы в книге «Дизайн и развитие C ++».

3 голосов
/ 12 апреля 2010

На самом деле, это не то же самое. 12,1 / 1:

Конструкторы не имеют имен

Единственный способ вызвать конструктор - использовать определенный синтаксис конструирования / преобразования объекта: он не найден при поиске имени функции, и вы не можете получить адрес конструктора. Это, наверное, хорошая вещь.

Полагаю, что синтаксис объявления конструктора мог выглядеть примерно так:

struct Foo {
    int a;
    constructor(int a) : a(a) { }
};

Но для этого потребовалось бы дополнительное зарезервированное слово, constructor. Это означало бы, что код для объявления конструктора меньше похож на код для конструирования объекта. Единственным «преимуществом» будет освобождение «Foo» для использования в качестве имени функции-члена. Это звучит не очень полезно для меня, тем более что вы потеряете «конструктор» в качестве имени функции-члена. Если бы был какой-то протест для Foo в качестве имени функции-члена, я думаю, это могло бы быть достигнуто по-другому, например, с помощью немного отличающегося синтаксиса, объявляем конструктор (+ Foo, возможно, для ~ Foo, возможно?) Так что я думаю, что не было.

Я не могу сразу увидеть какой-либо смысл наличия «именованных конструкторов» в C ++. Если вам нужна статическая функция-член Foo, которая принимает определенные параметры и возвращает Foo, вы можете объявить ее следующим образом:

struct Foo {
    static Foo bar(int);
};

и «использовать его как конструктор», например:

Foo f = Foo::bar(12);
2 голосов
/ 12 апреля 2010

Если вы хотите, чтобы конструктор вызывал конструктор базового класса в качестве инициализатора, вам необходимо указать его имя конструктора. Это было бы сложно, если бы все они были названы одинаково. например,

class Animal {
public:
   Animal();
};

class Dog {
public:
   Dog();
};

Animal::Animal() {
   // Base class constructor
}

Dog::Dog() : Animal() {
   // Derived class constructor, calling the base constructor as an initializer
}
1 голос
/ 12 апреля 2010

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

1 голос
/ 12 апреля 2010

Потому что так сказано в спецификации языка. В некоторых языках, таких как Python, это не так.

0 голосов
/ 12 апреля 2010

Конструктор вызывается каждый раз, когда создается объект, и обычно это происходит автоматически, т. Е. Компилятор вызывает конструктор, который является вызовом функции, который не имеет возвращаемого типа данных. Поэтому язык C ++ решил назвать эту функцию именем класса.

0 голосов
/ 12 апреля 2010

Я предполагаю, что вы довольно плохо знакомы с C ++ и, возможно, даже с объектно-ориентированным программированием. Итак, во-первых, я надеюсь, вы понимаете, что такое конструктор класса.

Большинство типов будет иметь какой-либо конструктор, используемый для инициализации себя. Даже когда речь идет о примитивах int или других типах переменных, все может быть инициализировано². Поэтому при создании классов вас попросят предоставить инициализатор, который называется constructor . Конструкторы могут иметь параметры, которые могут быть обязательными или нет. Они также могут быть перегружены, что означает, что класс может иметь много конструкторов.

Поскольку конструкторы являются инициализаторами, их вызов неявный: конструктор класса будет вызываться каждый раз, когда вы создаете объект этого класса, будь то с помощью ключевого слова new или путем объявления его в стеке:

CMyObject obj;

Теперь они должны быть объявлены внутри вашего класса. В конце концов, это методы ... как же его назвать? Например, Python использует другой подход и использует ключевое слово __init__; Дизайнер C ++ решил, что это будет имя класса.

Это имеет смысл, поскольку, в конце концов, наличие метода-члена с именем класса может вызвать конфликты имен (неоднозначность) по всей системе. (Несмотря на то, что эта серия статей посвящена C #, в нем разъясняется, почему использование имени для члена определенной области видимости с таким же именем является неправильным)

² Но иногда они не для того, чтобы уменьшить стоимость времени выполнения.

0 голосов
/ 12 апреля 2010

Какие есть альтернативы? Может быть:

  • Изобретите новое ключевое слово, чтобы указать конструктор как таковой
  • Иметь одно имя для всех конструкторов (например, new()).

Оба эти варианта кажутся менее желательными, чем действительность.

...