Programar em C++/Estruturas: diferenças entre revisões

[edição não verificada][edição verificada]
Conteúdo apagado Conteúdo adicionado
m Foram revertidas as edições de 191.189.86.158 (disc) para a última revisão de Defender
Linha 1:
 
{{Indentar}}
{{Indentar}}a jhbvlkjadhbvldafvbhlkdajhb gnlvuyhguliaefhkl buhlnerjthl vnjkahtgjbryumujmnju {{Indentar/fim}}
== Breve revisão ==
 
=== Conceito ===
Da linguagem "C" também temos o conceito de estrutura, do qual faremos uma pequena revisão agora. Como todos sabemos, nem todos os dados que precisamos usar podem ser agrupados em matrizes. Frequentemente usamos dados de diversos tipos diferentes, com tamanhos diferentes. Para tipos de dados de diferentes tamanhos existem estruturas de armazenamento de dados heterogêneos.
 
O especificador '''struct''' é usado para esta finalidade. Com ele podemos criar tipos que armazenam dados compostos por agrupamentos de outros tipos primitivos da linguagem. Geralmente, os dados são armazenados de forma a facilitar a identificação de cada campo de dados que pretende-se manter, para isso usamos nomes para cada campo dentro da estrutura de dados, de forma a ter um meio de acessá-la depois.
 
Estruturas são blocos básicos de informação e são manipulados de maneira primitiva. Basicamente o compilador instrui a montagem de um código que manipula-as de forma a copiar, referenciar e obter posição na memória. Todas as outras formas de tratar os dados devem ser providas pelo código do programa.
 
=== Implementação ===
 
Para criar um tipo de dados composto heterogêneo, basicamente, cria-se uma lista de tipos e nomes de variáveis separadas por ponto e vírgula. Podemos imaginar esta lista como um bloco de código, em linguagem C, onde estão presentes apenas as declarações de variáveis. Para isso temos a seguinte sintaxe:
 
<source lang=cpp>
struct Estrutura
{
<Tipo A> NomeVariavelA;
<Tipo A> NomeVariavelA2;
<Tipo A> NomeVariavelA3;
<Tipo B> NomeVariavelB;
<Tipo C> NomeVariavelC;
<Tipo D> NomeVariavelD;
...
...
<Tipo Z> NomeVariavelZ;
 
 
} [<NomeVariavelComposta>];
</source>
 
O nome da variável composta pode ser omitido na declaração da estrutura e depois definido onde for mais apropriado, geralmente, dentro de algum bloco de código onde venha a ser usado. Podemos ver logo abaixo, o exemplo de uma declaração de estrutura:
 
<source lang=cpp>
struct Estrutura
{
int Inteiro;
double PontoFlutuante;
char Caracteres[10];
};
 
int main()
{
Estrutura MinhaVariavelComposta;
...
...
...
return 0;
}
</source>
 
=== Acessando dados internos ===
 
O modo de acesso a variáveis internas de uma estrutura é feito através do operador ponto ".", porém, quando usamos ponteiros para guardar o endereço de uma estrutura usamos o operador seta "->". Vejamos um pequeno trecho de código:
 
<source lang="cpp">
Estrutura st;
Estrutura *pst;
st.Inteiro = 200;
 
pst = &st;
pst->PontoFlutuante = 23.976;
</source>
 
== Estruturas em C++ ==
 
As estruturas em C++ funcionam de modo análogo ao apresentado em linguagem "C". A diferença, a princípio, notável entre elas nas duas linguagens é que em "C++" o especificador '''struct''' não precisa ser escrito quando criamos a estrutura:
 
Em C, para criar uma estrutura de dados chamada '''st''', declaramos:
<source lang="C">
struct Estrutura st;
</source>
 
Para fazer o mesmo em C++, declaramos:
<source lang="cpp">
Estrutura st;
</source>
 
 
Este simples detalhe revela uma característica importante das estruturas em C++: Nesta linguagem as estruturas são tratadas como tipos primitivos de objetos. Elas têm características semelhantes às classes, que veremos nos capítulos subsequentes.
 
As estruturas em C++ também podem conter funções além de dados. Este fato vem da ideia de modelo de objeto que as estruturas mantém nesta linguagem. Objetos devem ter propriedades (variáveis) e métodos (funções membro), por isso temos a possibilidade de criar funções dentro do corpo das estruturas, com a finalidade de lidar com os dados que elas mantém.
 
== Construtores ==
Os construtores são funções que são criadas automaticamente sempre que tentamos criar um objeto. Eles funcionam da mesma maneira que construtores de classe. A esses que são criados automaticamente são os chamados de defaut.
 
Se escrevermos o código:
<source lang="cpp">
#include <iostream>
#include <string>
using namespace std;
const int MAX = 3;
 
struct Person
{
string name;
int height;
};
 
int main ()
{
Person p1;
cout << "The person's name is " << p1.name << " and height is " << p1.height << endl;
system (“pause”);
return 0;
}
</source>
 
O resultado é:
The person's name is and height is -858993460
 
Aqui é criado um defaut constructor no momento em que criamos a instância p1 ie com a linha Person p1;
 
Como as variáveis membro não foram iniciadas, o valor de name está vazio e o na variável height está um valor qualquer – que é lixo!
 
;Constructor sem argumentos
 
Podemos ter um construtor sem argumentos que ao contrário do defaut constructor designa valores defaut às variáveis membro.
<source lang="cpp">
struct Person
{
string name;
int height;
Person() //construtor sem argumentos
{
name = "No name assigned";
height = -1;
}
};
</source>
 
*O nome do construtor é sempre igual ao nome da estrutura, sem exceção.
*O construtor não retorna qualquer valor, sem exceção
 
Refazendo o nosso exemplo
<source lang="cpp">
#include <iostream>
#include <string>
using namespace std;
const int MAX = 3;
struct Person {
string name;
int height;
Person()
{
name = "No name assigned";
height = -1;
}
};
int main ()
{
Person p1;
cout << "The person's name is "<< p1.name << " and height is " << p1.height << endl;
system (“pause”);
return 0;
}
</source>
 
Repare que demos valores defaut ás variáveis. Agora não estamos no caso de ter p1.name=???
Por mais instâncias que criemos eles vão ter sempre valores padrão.
 
;Constructor com argumentos
 
Termos um constructor sem argumentos é um melhoramento face ao defaut constructor pois agora temos valores defaut para as variáveis membro.
Porém seria melhor se conseguíssemos inicializar as variáveis membro com valores dados pelo utilizador enquanto o programa estivesse e a correr. E realmente podemos fazer se passarmos argumentos.
<source lang="cpp">
#include <iostream>
#include <string>
using namespace std;
const int MAX = 3;
struct Person
{
string name;
int height;
Person() //constructor sem argumentos
{
name = "No name assigned";
height = -1;
}
Person(string s, int h) //constructor com 2 argumentos
{
name = s;
height = h;
}
};
int main ()
{
int metro;
string strName;
cout << "Entre com o nome da pessoa: ";
getline(cin, strName);
cout << "Enter height in metro: ";
cin >> metro;
cin.ignore();
Person p1(strName,metro);
cout << "The person's name is " << p1.name << " and height is " << p1.height << endl;
system (“pause”);
return 0;
}
</source>
 
Repare que os argumentos do construtor têm de estar na ordem esperada
 
;Separar o construtor prototype da implementação
<source lang="cpp">
#include <iostream>
#include <string>
using namespace std;
const int MAX = 3;
struct Person {
string name;
int height;
Person(); //construtor sem argumento
Person(string, int); //construtor com dois parâmetros, apenas é necessário dizer o tipo dos parâmetros – o nome não é necessário)
};
Person::Person()
{
name = "No name assigned";
height = -1;
}
Person::Person(string s, int h)
{
name = s;
height = h;
}
int main ()
{
int metro;
string strName;
cout << "Enter person's name: ";
getline(cin, strName);
cout << "Enter height in inches: ";
cin >> metro;
cin.ignore();
Person p1(strName, inches);
cout << "The person's name is " << p1.name << " and height is " << p1.height << endl;
system (“pause”);
return 0;
}
</source>
 
* Vamos ver a função main(): declarámos 2 variáveis uma int e outra string. Pedimos para a pessoa escrever o nome e colocámos o valor na variável string, depois pedimos a altura e colocámos na variável int. Depois chamámos o construtor com dois argumentos e passamos as variáveis anteriores como argumentos. Por fim mandámos imprimir os valores das variáveis membro da estrutura.
* Repare que para definirmos fora o construtor recorremos ao operador scope ::
<source lang="cpp">
Person::Person()
Person::Person(string s, int h)
</source>
* Repare que no prototype dos construtor apenas tivemos de dizer o tipo dos parâmetros
 
 
{{Indentar/fim}}
{{AutoCat}}