То, почему то имя конструктора, является тем же как имя класса?
Согласно Страуструпу, поскольку альтернатива новой функции «была источником путаницы». См. «Дизайн и эволюция C ++», раздел 3.11.2, хотя это полное обоснование, которое я цитировал.
Редактировать: Как уже отмечалось, существует ряд альтернативных решений. Smalltalk, например, делает следующее:
myclass new
отправляет «новое» сообщение объекту класса myclass. Очевидно, что решение C ++ здесь было бы немного глупым:
myclass myclass
явно не имеет смысла.
Delphi, OTOH, позволяет любой именованной функции быть конструктором, пометив ее как таковую:
constructor Create;
constructor FooBar;
оба будут подходящими именами конструктора для любого класса. Как и в случае с Smalltalk, вам необходимо вызвать их в объекте класса:
myclass.Create;
Из всех этих решений я считаю C ++ одним из самых элегантных, и я могу понять, почему он почти повсеместно принят языками-преемниками.
Это просто вопрос определения языка. Компилятор знает, что методы с тем же именем являются конструктором. Это также делает создание объектов этого класса очень понятным, любой, кто не знает класса, знает, что если имя равно, это конструктор.
В исходном «C с классами» этого не было - он был назван «новый», IIRC. В любом случае, на большинство вопросов «почему» о C ++ вы можете найти ответы в книге «Дизайн и эволюция C ++».
Если вы хотите, чтобы конструктор вызывал конструктор базового класса в качестве инициализатора, вам нужно будет указать его имя конструктора. Было бы сложно, если бы все они были названы одинаково. например
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
}
На самом деле, это не одно и то же. 12.1/1:
Конструкторы не имеют имен
Единственный способ вызвать конструктор - это использовать специфический синтаксис построения/преобразования объекта: он не находится поиском по имени функции, и вы не можете взять адрес конструктора. Это, вероятно, хорошо.
Я полагаю, что синтаксис объявления конструктора мог бы выглядеть примерно так:
struct Foo {
int a;
constructor(int a) : a(a) { }
};
Но это потребовало бы дополнительного зарезервированного слова, constructor
. Это означало бы, что код для объявления конструктора меньше похож на код для создания объекта. Единственной "выгодой" было бы освобождение "Foo" для использования в качестве имени функции-члена. По-моему, это не слишком полезно, особенно если учесть, что вы потеряете "constructor" как имя функции-члена. Если бы было какое-то возмущение по поводу Foo как имени функции-члена, я думаю, этого можно было бы добиться по-другому, например, используя немного другой синтаксис для объявления конструктора (+Foo, в дополнение к ~Foo, возможно?). Так что я думаю, что нет.
Я не могу сразу понять, какой смысл в "конструкторах с именем пользователя" в C++. Если вам нужна статическая функция-член Foo, которая принимает определенные параметры и возвращает Foo, вы можете объявить ее так:
struct Foo {
static Foo bar(int);
};
и "использовать ее как конструктор" так:
Foo f = Foo::bar(12);
Потому что так говорится в спецификации языка. В некоторых языках, таких как Python, это не так.
Я предполагаю, что вы довольно новичок в C++ и, возможно, даже в объектно-ориентированном программировании. Поэтому, во-первых, я надеюсь, вы понимаете, что такое конструктор класса.
Большинство типов имеют какой-то конструктор, используемый для инициализации. Даже если говорить о примитивах int
s или других типах переменных, все может быть инициализировано². Поэтому при создании классов вас просят предоставить инициализатор, называемый конструктором. Конструкторы могут иметь параметры, которые могут быть обязательными или нет. Они также могут быть перегружены, что означает, что класс может иметь много конструкторов.
Поскольку конструкторы являются инициализаторами, обращение к ним неявно: конструктор класса будет вызываться каждый раз, когда вы создаете объект этого класса, будь то с помощью ключевого слова new
или объявляя его в стеке:
CMyObject obj;
Итак, они должны быть объявлены внутри вашего класса. В конце концов, это же методы... так как же они должны называться? Python, например, использует другой подход и использует для этого ключевое слово, __init__
; разработчик C++ решил, что его именем будет имя класса.
Это имеет смысл, поскольку, в конце концов, наличие метода-члена с именем класса может привести к столкновению имен (неоднозначности) в системе. (Хотя эта серия статей посвящена C#, в ней разъясняется, почему использование имени для члена определенной области видимости, имеющего такое же имя, плохо)
² Но иногда этого не делают, чтобы уменьшить затраты времени на выполнение.
Какие есть альтернативы? Возможно:
new ()
). Оба эти варианта кажутся менее желательными, чем на самом деле.
Конструктор вызывается каждый раз, когда создается объект, и обычно это происходит автоматически, т.е. компилятор вызывает конструктор, который является вызовом функции, не имеющей возвращаемого типа данных. Поэтому язык C++ решил назвать эту функцию именем класса.
Стандарт языка C ++:
12.1. У конструкторов нет имен.
Ваш вопрос основан на недоразумении. Конструкторы используют специальный синтаксис объявления, где имя класса снова используется вместо имени члена. Я не вижу ничего плохого в этом синтаксисе, поэтому я даже не могу представить, что может вызвать ваш вопрос (что затрудняет, если не делает невозможным ответить).
Тем не менее, у конструкторов в C ++ нет имен. Им просто не нужны имена, потому что в C ++ нет контекста, в котором вам нужно было бы ссылаться на конструктор.