2010-04-12 4 views
6

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

+0

Ну ... Почему бы и нет? Другими словами, невозможно ответить на ваш вопрос до тех пор, пока вы не объясните, почему возник вопрос. – AnT

+0

@AndreyT: ОП спрашивает, почему langauge был спроектирован именно так. Я думаю, что ответ Нила Баттерворта доказывает, что возможен осмысленный ответ. – Cascabel

+0

@AndreyT: например, в конструкторах VB.NET используется специальное имя метода 'New'. Можно было бы видеть это как более ясное. Я почти уверен, что буду иметь, когда сначала изучаю C++. –

ответ

1

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

1

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

5

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

10

Согласно Stroustrup, поскольку альтернатива новой функции «была источником путаницы». См. The Design & Evolution of C++, раздел 3.11.2, хотя это полное оправдание, которое я цитировал.

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

myclass new 

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

myclass myclass 

, очевидно, неразумно.

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

constructor Create; 
constructor FooBar; 

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

myclass.Create; 

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

+0

+1 Это тот момент, который я пытался сделать ... но это связано с документацией. –

+0

@ Justin: Я думаю, что ваш ответ был несколько несправедливо критикован - комментарии указывали, что в пределах определенного стандарта C++ нет необходимости в вызове named для конструктора, когда точка была именно тем, что определенный стандарт позволяет ему работать сюда. – Cascabel

2

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

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 
} 
+0

'Dog :: Constructor(): Animal :: Constructor() {}' –

+0

Я говорю сложно; но не является неосуществимым. С радостью, спецификация C++ не выбрала этот синтаксис. – spoulson

9

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

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

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

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

3

Собственно, это не то же самое. 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); 
0

Каковы альтернативы? Возможно:

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

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

+0

что не так с новым ключевым словом, чтобы указать конструктор - если предположить, что мы смотрим на новый язык? – sivabudh

+0

@ ShaChris23: Я отчетливо не сказал, что было что-то * неправильное * с идеей, просто решение C++ было субъективно лучше. Если ключевые слова являются * зарезервированными словами * и не могут использоваться как * идентификаторы * (как они есть на C++), то чем меньше, тем лучше. Решение C++ для идентификации конструктора делает такое ключевое слово полностью избыточным. – Clifford

+0

Да, я согласен с тем, что вы сказали. – sivabudh

0

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

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

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

CMyObject obj; 

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

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

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

+0

Неверно сказать, что конструкторы, являющиеся инициализаторами, являются причиной того, что их вызовы неявны. Конструкторы также являются инициализаторами в Delphi, но вызовы на них явны, и они могут иметь любое имя, которое вы хотите. –

0

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

+1

Что со спамом, а? – GManNickG

+0

Детали после "поэтому" не следуют от части раньше! – Clifford

Смежные вопросы