Professional Documents
Culture Documents
C++
Normas de estilo en C++
Igual que escribir en un idioma tiene una serie de normas de
estilao, que, si se cumplen, hacen el texto ms comprensible y
elegante, igual los lenguajes de programacin tienen una serie
de normas de estilo, para hacer su cdigo ms elegante,
comprensible e incluso fcil de depurar. En C++, las normas de
estilo parten del diseo correcto de las clases, de la utilizacin
correcta de la herencia y de la encapsulacin, y del
aprovechamiento de todas las capacidades de C++.
Simultneamente, veremos como los conceptos fundamentales
de la programacin orientada a objetos, tales como la herencia y
encapsulacin se implementan en C++.
Forma cannica
La forma cannica es la forma ortodoxa de declarar una clase en
C++. Permite evitar problemas de programacin, y permite que
una clase declarada de esta forma se pueda usar de la misma
manera que cualquier tipo tradicional de C.
En la forma cannica, evidentemente, tienen que entrar el
constructor y el destructor.
class miClase {
public:
/// Constructor
miClase() {};
/// Destructor
~miClase() {};
}
otroTipoVariable repVariableInstancia2;
}
/// Destructor
~miClase() {};
protected:
tipoVariable& variableInstancia1() {
return repVariableInstancia1;
}
const tipoVariable& variableInstancia1() const
{
return repVariableInstancia1;
}
private:
tipoVariable repVariableInstancia1;
otroTipoVariable repVariableInstancia2;
}
class miClase {
// Dejar todo lo dems, y aadir alguna funcin
/// Mtodo puesto solo para heredar
void metodo( void ) const; {
// Una implementacin del mtodo
}
}
/// Esta subclase es una subclase tonta que no hace
nada en realidad
class miSubclase: public miClase {
/// Mtodo puesto solo para heredar
void metodo( void ) const; {
}
}
// Llama a miClase::metodo
refZape = zipi;
refZape.metodo();
// Llama a miSublase::metodo
// Conversion
Las funciones virtuales sirven para una cosa ms: dado que
definen el interfaz de una clase, existen en C++ las funciones
virtuales puras que slo definen un interfaz, sin aportar
(habitualmente) ningn cdigo, y obligando adems a las clases
derivadas a implementar ese cdigo. Un caso clsico de estas
funciones o mtodos virtuales puros es el mtodo que imprime la
clase a un canal de salida:
class miClase {
// eliminados los comentarios y cdigo para dejarlo
todo ms claro
public:
miClase() {};
miClase( const miClase& _c );
const miClase& operator=( const miClase& _c );
virtual ~miClase() {};
virtual void metodo( void ) const;
virtual void printSelf(
ostream& _o) const = 0; // mtodo virtual puro
protected:
tipoVariable& variableInstancia1();
const tipoVariable& variableInstancia1()
const
private:
tipoVariable repVariableInstancia1;
otroTipoVariable repVariableInstancia2;
}
/// Esta subclase es una subclase tonta que no hace
nada en realidad
class miSubclase: public miClase {
public:
miSubclase(): miClase(), varInstSubclase() {};
}
// Pero es ms fcil hacerlo as
class miCBA{
public:
void a() = 0;
void b( foo& ) = 0;
}
/** T debe descender de la clase miCBA */
template<class T> void baz<T>( const T& _t){
_t.a();// y ms cosas
foo miFoo;
_t.b( miFoo );
}
Ms formas de construir
Aunque un constructor propio, con ms o menos sofisticacin es
la forma habitual de construir una clase, hay clases que no
tienen porqu saber como construirse. O, en algunos casos, toda
la complejidad del constructor de un objeto hay que encapsularla
en otro objeto, que sabr como construirlo. Por ejemplo, en
entornos de aplicaciones tales como
COM
(Common Object Model, de Microsoft), es necesario disear factoras para todos los
objetos, de forma que los clientes que los usen no tengan que saber como construir cada
objeto especfico.
private:
tipoVariable repVariableInstancia1;
otroTipoVariable repVariableInstancia2;
}
class miSubclase: public miClase {
public:
miSubclase(): miClase(), varInstSubclase() {};
miSubclase( const miSubclase& _c )
:miClase( _c ),
varInstSubclase( _c.varInstSubclase) {};
const miClase& operator=( const miClase& _c );
virtual ~miClase() {};
virtual void metodo( void ) const;
virtual const miClase*
clone() const; {
return new
miSubclase(*this)
}
virtual void printSelf(
ostream& _o) const;
private:
tipoVar varInstSubclase;
}
public:
miClase() {};
miClase( const miClase& _c );
const miClase& operator=( const miClase& _c );
virtual ~miClase() {};
virtual void metodo( void ) const;
/** Ctor virtual de copia; devuelve un puntero
constante para que no
se pueda usar como operador de asignacin. Sin
implemtacin:
Un objeto que no se puede instanciar no sepuede
copiar
*/
virtual const miClase* clone() const = 0;
virtual void printSelf(
ostream& _o) const = 0;
protected:
tipoVariable& variableInstancia1();
const tipoVariable& variableInstancia1()
const
private:
tipoVariable repVariableInstancia1;
otroTipoVariable repVariableInstancia2;
}
class miSubclase: public miClase {
public:
miSubclase(): miClase(), varInstSubclase() {};
miSubclase( const miSubclase& _c )
:miClase( _c ),
varInstSubclase( _c.varInstSubclase) {};
const miClase& operator=( const miClase& _c );
virtual ~miClase() {};
virtual void metodo( void ) const;
virtual const miClase*
clone() const; {
return new
miSubclase(*this)
}
virtual void printSelf(
ostream& _o) const;
private:
tipoVar varInstSubclase;
}