Quero dizer, é uma questão de escolher palavras mais do que existe alguma diferença entre a função e a chamada do construtor. A coisa chamada "construtor de um objeto" também pode ser chamada "função com o nome object
retornando tipo object
".
Alguém poderia argumentar que o C ++ não permite ter a mesma função e tipo de nome; no entanto, há uma solução alternativa para fazer isso. O C ++ possui um açúcar sintático especial (chamado de construtor) com o qual você pode criar uma função com o object
tipo de retorno de nome object
. Então eu acho que um construtor pode ser visto e usado como uma função independente.
Há algumas diferenças semânticas importantes que estou sentindo falta aqui?
c++
functions
constructors
type
user3123061
fonte
fonte
Respostas:
Um construtor é basicamente um método, sim, mas é um método especial.
Por exemplo, em C ++, um construtor não é simplesmente uma função que retorna uma nova instância desse tipo. Se fosse, a herança não funcionaria. Você não poderia chamar os construtores de base, porque eles retornariam uma nova instância também. Você terminaria com uma nova instância de A, que será retornada ao construtor de B, que cria uma nova instância de B, que será retornada ao construtor de C, etc.
Em vez disso, um construtor é mais um método de inicialização chamado automaticamente pelo alocador de instância. Quando você diz "novo" para criar um objeto no heap, ele aloca a memória para o tipo solicitado (usando um alocador de memória, como malloc) e chama o método construtor nele. O compilador possui regras especiais para como e em que ordem esse construtor pode chamar os outros construtores. Por exemplo, em C #, se você não chamar explicitamente um construtor de base, o compilador adicionará uma chamada ao construtor padrão de base.
São essas regras sobre como o compilador manipula os construtores que o diferenciam de "uma função chamada .ctor que retorna uma instância do tipo".
fonte
new
para construir objetos em C ++, pois ele possui variáveis automáticas.Não, um construtor de
object
é muito diferente de uma função chamadaobject
e retornandoobject
. Um construtor não tem nome, mas isso é em grande parte um detalhe técnico. As diferenças mais importantes são que um construtor não tem tipo de retorno e que não pode ser chamado diretamente.Um construtor não retorna nada porque recebe um bloco de memória e opera nessa memória no local. Pode ajudar se você esquecer o nome "construtor" por um momento e pensar nele como inicializador . O objetivo do construtor não é construir um objeto "do nada". Seu objetivo é inicializar um objeto no local exato da memória onde ele precisa estar.
Se um construtor retornasse um objeto, esse objeto retornado (o valor retornado) teria que morar em algum lugar (provavelmente na pilha) e, ali, ele precisaria ser inicializado de alguma forma - estamos executando um loop aqui.
Isso anda de mãos dadas com o fato de que um construtor nunca pode ser chamado diretamente. Se você tem uma classe
object
e usa uma expressão emobject()
algum lugar, ela não possui a semântica de "chamar o construtor deobject
". Possui a semântica de "criar um objeto temporário do tipoobject
". O compilador traduz isso em alocar algum lugar para o temporário morar (provavelmente / geralmente na pilha) e chamar o construtor para construir (= inicializar) um objeto naquele local.O mesmo princípio se aplica ao usar
new object()
. Esta é uma nova expressão, que faz duas coisas:operator new
(que retorna avoid*
) para alocar memória não processada para o objeto.Pensando em um construtor de
object
como uma função como esta:está errado. Se alguma coisa, a maneira como um construtor trabalha é mais próxima disso:
Com a exceção de que você nunca pode chamá-lo diretamente. Ele sempre é chamado apenas quando especificado por uma construção de idioma diferente. Mesmo o posicionamento new (também conhecido como o truque "chame um construtor aqui"),
new (&place_for_object) object()
não chama o construtor diretamente. Ele se traduz em uma chamada para a forma nova colocação,operator new
que retorna seu argumento, seguida por uma chamada para o construtor (como qualquer outra nova expressão).fonte
Sua tentativa de reformular está incorreta.
Embora um construtor se pareça com uma função de membro com um nome igual ao nome da classe, o fato é que um construtor realmente não tem um nome. Isso é explicitamente declarado no padrão C ++ (seção [class.ctor] / 1):
Tanto quanto: "Eu acho que um construtor pode ser visto e usado como uma função independente" vai ... bem, eu não tenho muita certeza do que você quer dizer. Uma função livre certamente não pode ser um construtor - um construtor deve ser um membro de uma classe. Ao mesmo tempo, você certamente pode definir uma função livre que cria um objeto e retorna uma instância desse objeto. Essa função livre pode até (mais ou menos) ter o mesmo nome que o tipo de objeto que ela cria, se você desejar o suficiente. Por exemplo, você pode definir a classe dentro de um espaço para nome e, em seguida, definir uma função fora do espaço para nome:
Esse não é realmente o mesmo nome (a função é justa
bar
e a classe éfoo::bar
), mas, dependendo do seu ponto de vista, você pode vê-los dessa maneira.Essa função livre não teria as outras características principais de um construtor. A invocação de um construtor pode ser completamente implícita. Por exemplo, se eu tiver uma classe como:
... então codifique como:
... pode criar um objeto foo temporário a partir do qual
1
ele pode passar esse objeto foofoo::operator+
. Isso simplesmente não acontecerá com uma função livre, mesmo se essa função livre tiver sido definida para pegar o tipo de parâmetro correto e retornar o tipo de resultado necessário. Para uma conversão implícita, é necessário um construtor.fonte
Primeiro, os construtores não retornam nada e, como conseqüência, não têm tipos de retorno.
Segundo, os construtores são diferentes, pois você não pode realmente chamar o construtor diretamente de uma maneira que chama funções. Em vez disso, se você declarar uma variável, os construtores apropriados serão chamados pelo tempo de execução.
Terceiro, no caso de herança, funções regulares nas subclasses substituem as funções nas classes pai. Os construtores, por outro lado, construtores de classe pai em cascata são chamados primeiro e, em seguida, subclasse de construtores.
Quarto, os construtores podem ter listas de inicialização, enquanto a função "normal" não pode.
fonte