Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - Namida

#1
¡Buenas señores! He estado trabajando en un código que me permita trabajar con listas simples a modo de array dinámico y este es el resultado. La idea era que el comportamiento final de la clase fuera fácil e intuitivo, y espero haberlo conseguido  ;-)... Sin embargo la mayor limitación de mi trabajo radica en la forma de agregar los datos, pues sólo se puede introducir a la cabeza o a la cola de la lista, y no de forma aleatoria. A pesar de ello espero que les pueda servir de ayuda en códigos más complicados  :D

Código (cpp) [Seleccionar]

// Autor: Namida
// Fecha: 04 enero 2011

/// DIRECTIVAS GENERALES DEL PREPROCESADOR
#define _list_

#ifndef NULL
#define NULL 0
#endif

#define OFF false
#define ON true


///CODIGO
// Declaraciones Previas
template<typename TYPE> class list;
template<typename TYPE> list<TYPE> &operator < (list<TYPE> &L,TYPE X);
template<typename TYPE> list<TYPE> &operator > (list<TYPE> &L,TYPE X);
template<typename TYPE> list<TYPE> &operator ~ (list<TYPE> &L);

// Declaracion
template<typename TYPE> class list
{
private:

/*Definicion del nodo*/
struct node{
TYPE data;
node* next_node;
};

/*Informacion sobre la lista*/
node* first_node;
unsigned list_size;
bool delete_mode;

public:

/*Constructor de clase*/
list();

/*Operadores*/
//Escritura
friend list<TYPE> &operator < <TYPE>(list<TYPE> &L,TYPE X);
friend list<TYPE> &operator > <TYPE>(list<TYPE> &L,TYPE X);
//Lectura
TYPE operator [] (unsigned N);
//Borrado
friend list<TYPE> &operator ~ <TYPE>(list<TYPE> &L);

/*Descriptor*/
unsigned Size();

};

// Metodos
/*Constructor*/
template<typename TYPE> list<TYPE>::list(){
first_node=NULL;
list_size=0;
delete_mode=OFF;
};
/*Operadores*/
//Escritura
template<typename TYPE> list<TYPE> &operator < (list<TYPE> &L,TYPE X){
list<TYPE>::node* new_node=new list<TYPE>::node;
new_node->data=X;
new_node->next_node=NULL;

if (L.first_node!=NULL){
list<TYPE>::node* aux_node=L.first_node;
while (aux_node->next_node!=NULL){
aux_node=aux_node->next_node;
};
aux_node->next_node=new_node;
}else{
L.first_node=new_node;
};
L.list_size+=1;
return L;
};
template<typename TYPE> list<TYPE> &operator > (list<TYPE> &L,TYPE X){
list<TYPE>::node* new_node=new list<TYPE>::node;
new_node->data=X;
new_node->next_node=L.first_node;
L.first_node=new_node;
L.list_size+=1;
return L;
};
//Lectura
template<typename TYPE> TYPE list<TYPE>::operator [] (unsigned N){
try{
if (N<list_size){
switch (delete_mode){
case OFF:
{
node* aux_node=first_node;
for(unsigned i=0;i<N;i++){
aux_node=aux_node->next_node;
};
return aux_node->data;
};
case ON:
{
if (N==0){
node* aux_node=first_node;
first_node=aux_node->next_node;
delete aux_node;


}else{
node* aux_node=first_node;
for(int i=0;i<int(N)-1;i++){
aux_node=aux_node->next_node;
};
node* delete_node=aux_node->next_node;
aux_node->next_node=aux_node->next_node->next_node;
delete delete_node;
};
list_size-=1;
delete_mode=OFF;
throw 0;
};
};
}else{
throw 0;
};
}catch(int code){
TYPE X=TYPE();
return X;
};
};
//Borrado
template<typename TYPE> list<TYPE> &operator ~ (list<TYPE> &L){
L.delete_mode=ON;
return L;
};

/*Descriptor*/
template<typename TYPE> unsigned list<TYPE>::Size(){
return list_size;
};

#undef OFF
#undef ON


Un ejemplo de su uso
[/size]
Código (cpp) [Seleccionar]

#include"list.h"

int main(int argc,char* argv[]){

//Creacion de una lista tipo int
list<int> L=list<int>();

/* Agregar datos
A la cola*/
L<0<1<2<3<4;
/*A la cabeza*/
L>5>6;

//Estado actual de la lista: 6-5-0-1-2-3-4

//Leer informacion de la lista
L[1]; //Devuelve el numero 5

//Borrado
(~L)[1]; //Elimina el numero 5 de la lista

L.Size(); //Devuelve el tamagno de la lista

return 0;
};
#2
Solucionado:

Declaraciones previas; clase y operadores

template<typename TYPE>class obj;
template<typename TYPE>obj<TYPE> &operator < (obj<TYPE> &OBJ, TYPE X);


Declaración de la clase:

template<typename TYPE>class obj{
    [...]
    friend obj<TYPE> &operator < <TYPE> (obj<TYPE> &OBJ, TYPE X);
};


Declaración del operador:

template<typename TYPE>obj<TYPE> &operator (obj<TYPE> &OBJ, TYPE X){
    [...]
    return OBJ;
};


Sin más, espero que les resulte de ayuda! :D!
#3
¡Hola a todos! Tengo el siguiente problema. No se como sobrecargar un operador dentro de una plantilla. Lo he intentando de la siguiente forma y me tira error.

template<TYPE>class A{
[...] /*Resto del código*/
friend std::ostream &operator << (std::ostream &os,A<TYPE> X);
};

template<TYPE> std::ostream &operator <<(std::ostream &os,A<TYPE> X){
[...] /*Resto del código*/
return os;
};


Gracias de antemano por su ayuda ;)
#4
¡Hola! Llevo bastante tiempo buscando sobre el tema pero no he encontrado nada sobre C++ referente al tema. Mi pregunta es si es posible asociar un icono al ejecutable (El archivo .exe, por si no se me entiende xD) desde el propio código¿? y de ser así, si serian tan amable de explicarme...

Muchas Gracias de antemano :D
#5
¡Muy Buenas!

Aqui os dejo mi pequeño aporte. Se trata de un código que se encarga de cargar 'palabras' de un fichero en una lista simple para que después pueda ser leida e interpretada por otro código. Espero os resulte útil, y cualquier error, duda o crítica que me comuniqueis será bienvenida. De antemano ¡Gracias!  :D

Nombre Original del Archivo: fword.h
#ifndef _FWORD_
#define _FWORD_
#endif

#ifndef _FSTREAM_
#include <fstream>
#endif

#ifndef NULL
#define NULL 0
#endif

struct L_word{
int wordc;
char* wordv;
struct L_word* next;
};
void L_word_add(struct L_word *&p,char* argv,int argc){
struct L_word* new_node;
struct L_word* aux_node;
new_node=new struct L_word;
new_node->next=NULL;
new_node->wordc=argc;
new_node->wordv=argv;
if(p==NULL){
p=new_node;
}else{
aux_node=p;
while(aux_node->next!=NULL){
aux_node=aux_node->next;
}
aux_node->next=new_node;
}
};
struct L_word* L_fword(char* file_name){
struct L_word* pointer=NULL;
fstream file(file_name,ios::in|ios::binary);
if(file.good()){
bool w=false;
while(!w){
int argc;
char aux;

do{
argc=0;
do{
file.read(reinterpret_cast<char*>(&aux),sizeof(char));
w=file.eof();
argc++;
}while((aux!=' ')&&(aux!='\n')&&(aux!='\t')&&(aux!='\0')&&(aux!=char(13))&&(!w));
}while((argc<2)&&(!w));

char* argv;
argv=new char[argc];

if(w){
file.clear();
file.seekg(-argc+1,ios::cur);
file.read(reinterpret_cast<char*>(argv),sizeof(char)*(argc-2));
file.read(reinterpret_cast<char*>(&aux),sizeof(char));
argv[argc-2]=aux;
}else{
file.seekg(-argc,ios::cur);
file.read(reinterpret_cast<char*>(argv),sizeof(char)*(argc-1));
}
argv[argc-1]='\0';
L_word_add(pointer,argv,argc);
file.seekg(1,ios::cur);
}
}
file.close();
return pointer;
};


Microsoft Visual Studio 2008
#6
¡Muy buenas!

Les comento. Desde hace tiempo llevo teniendo problemas al intentar liberar un array dinámico incluido en una clase, a traves de un destructor de clase.

A modo ilustrativo propongo el siguiente ejemplo:
class A{
private:
int** dato;
int Indice_1,Indice_2;
public:
void crear(int X,int Y){
//Se define el tamaño del array dato
Indice_1=X;
Indice_2=Y;
//Se reserva la memoria (Array Dinámico)
dato=new int *[X];
for(int i=0;i<X;i++){
dato[i]=new int [Y];
for(int j=0;j<Y;j++){
dato[i][j]=0;
}
}
}
~A(){
//Se libera la memoria
for(int i=0;i<Indice_1;i++){
delete[] dato[i];
}
delete[] dato;
}
};


El error que genera dice así:
Excepción no controlada en 0x102d31ea (msvcr90d.dll) en PRINCIPAL.exe: 0xC0000005: Infracción de acceso al leer la ubicación 0xfeeefee2.

Lo curioso del caso es que empleando el prefijo del destructor de clase ~ se produce el error pero, renombrando el algoritmo como una función void, esto no ocurre y funciona correctamente (se libera la memoria correctamente y el programa actua sin anomalías).

void borrarA(){
       //Se libera la memoria
       for(int i=0;i<Indice_1;i++){
delete[] dato[i];
}
delete[] dato;
}


Empleando el primer código, pero situando un testigo en el destructor (tipo cout<<"DESTRUCTOR INVOCADO"<<endl), resulta que éste es invocado dos veces.  Una, cuando yo lo llamo, y otra, cuando el programa intenta finalizar. Siendo esta segunda vez la que causa el error.

Por lo que mis preguntas son:
¿Por qué el destructor es invocado una segunda vez cuando la hinstancia de la clase ya se ha 'destruido'?
¿Por qué funciona correctamente bien con void y no asi con ~ (propio del destructor de clase)?

Menciono que empleo como compliador el Visual Studio C++ 2008... creo que los tiros van por aqui jeje

¡¡Gracias por la ayuda!!