[C con Clase] Un error con (¿...?) en GCC y no en Visual Studio (Parte III)
Steven Davidson
srd4121 en njit.edu
Sab Jul 10 05:32:52 CEST 2010
Hola Gilberto,
Gilberto Cuba Ricardo wrote:
> Hola Lista,
>
> He mantenido este título porque sigo teniendo errores durante una
> portación de códigos de Microsoft Visual Studio 2005 a GNU C/C++
> Compiler 3.4x >. Esta vez no he dejado el tema de las plantillas en
> el asunto porque a mi entender no lo es, pero no dejan de existir en
> mi código.
>
> A continuación muestro la lógica seguida y la generación de los
> códigos de errores que me van sucediendo. Una abstracción del código
> inicial donde me da el problema es el siguiente:
>
Veamos el código fuente.
> ----------------------------------------------------
> #include <string>
>
> class IClassTypeInfo
> {
> /* ... */
> };
>
> template <class T>
> class vmt_definition : public IClassTypeInfo
> {
> public:
> template <typename RT>
> void def_method(const std::string& name, RT (T::* fn) () )
> {
> }
> /* ... */
> };
>
> template < class Current, class Descendant >
> struct definition;
>
> template <class T>
> class ScriptType
> {
> public:
> template<class U>
> static IClassTypeInfo* resolve_definition()
> {
> [1] static definition<U, U> d_;
¿Estás seguro que quieres estos parámetros? Si es correcto, entonces es
posible que quieras definir la plantilla 'definition' para cualesquier
parámetros. De lo contrario, esta estructura debe ser:
'definition<MyFirstClass,MyFirstClass>' o
'definition<MyHeritClass,MyHeritClass>'.
> return &d_;
> }
> /* ... */
> };
>
> template <class T>
> class BasicScriptable : public ScriptType<T>
> {
> typedef ScriptType<T> self_t;
> /* ... */
> };
>
> class HeritableClass : public BasicScriptable<HeritableClass>
> {
> public:
> HeritableClass() {}
> public:
> void hered_first_method() {}
> void hered_second_method() {}
> };
>
> class MyFirstClass : public HeritableClass
> {
> public:
> virtual void method01() {}
> };
>
> class MyHeritClass : public MyFirstClass
> {
> public:
> [2] virtual IClassTypeInfo* get_typeInfo() { return resolve_definition<MyHeritClass>(); }
Esto significa que se retornará la dirección de memoria del objeto
estático de la estructura 'definition<MyHeritClass,MyHeritClass>'. Esta
clase fue generada a partir de la especialización parcial que
escribiste: 'struct definition<MyHeritClass, T>', donde T='MyHeritClass'.
> public:
> virtual void method_01() {}
> virtual void method_02() {}
> };
>
>
> template<typename T>
> struct definition<MyFirstClass, T> : public vmt_definition<T>
> {
> definition()
> {
> [3] def_method( "method1", &MyFirstClass::method01 );
Esto implica que los parámetros de 'def_method' serán RT='void' y
T='MyFirstClass'. Esto también implica que invocas
'vmt_definition<MyFirstClass>::def_method()'. Por consiguiente, esta
plantilla debe ser 'definition<MyFirstClass, MyFirstClass>'. Sin
embargo, debes ser explícito, ya que 'def_method()' no fue definida en
este ámbito sino en otro. Deberías escribir:
this->vmt_definition<T>::def_method( "method1", &MyFirstClass::method01 );
Ten presente que los punteros a los miembros de una clase no siguen las
reglas de herencia, sino de ámbito. Por lo tanto, el puntero a una
función miembro de 'MyFirstClass' no es "transferible" a un puntero de
otra clase.
El problema que estás teniendo es que instancias previamente un objeto
de la clase 'definition<MyFirstClass, MyHeritClass>'. Esto no concuerda
con lo que hemos mencionado antes y por tanto no encuentra una
definición de 'def_method()' adecuada.
Podría escribir:
vmt_definition<MyHeritClass>::def_method( std::string("method1"),
&MyHeritClass::method_01 );
Pero seguramente esto no es lo que querías hacer.
> }
> };
>
> template<typename T>
> struct definition<MyHeritClass, T> : public definition<MyFirstClass, T>
> {
> definition()
> [4] {
> [5] def_method( "method_01", &MyHeritClass::method_01 );
Aquí tienes algo parecido al caso anterior. Puedes escribir:
definition<MyFirstClass, T>::def_method( "method_01",
&MyHeritClass::method_01 );
> }
> };
>
> int main()
> {
> return 0;
> }
Espero haber aclarado algo de este tema.
Steven
Más información sobre la lista de distribución Cconclase