x64 visual una tener tan son sirve reflexion que programacion porque para numeros niños microsoft los library importantes importante importancia herencia hacer funciones funcion ejemplos dev descargar como clases años amigos amigas c++ visual-c++

visual - this c++



C++ no me deja hacer amigos (4)

Cuando compila Mesh.cpp , incluye Mesh.h , que incluye MeshList.h , que comienza a incluir Mesh.h pero se detiene antes de tiempo porque ahora se ha definido _MESH_H . Luego (de vuelta en MeshList.h ) hay una referencia a Mesh , pero eso aún no se ha declarado. Por lo tanto, por ejemplo, su error C2143.

Tengo dos clases, Mesh y MeshList. Quiero que MeshList tenga una función que pueda cambiar los miembros privados de Mesh. Pero no compilará y no sé por qué. Aquí está mi código.

Mesh.h

#ifndef _MESH_H #define _MESH_H #include "MeshList.h" #include <iostream> class Mesh { private: unsigned int vboHandle_; friend void MeshList::UpdateVBOHandle(); public: inline void Out() {std::cout << vboHandle_;} }; #endif

Mesh.cpp

#include "Mesh.h"

MeshList.h

#ifndef _MESH_LIST_H #define _MESH_LIST_H #include "Mesh.h" class MeshList { public: Mesh *mesh; //Line 11 Error void UpdateVBOHandle(); }; #endif

MeshList.cpp

#include "MeshList.h" void MeshList::UpdateVBOHandle() { *mesh->vboHandle_ = 4; }

Obtengo estos errores:

MeshList.h (línea 11)

  • error C2143: error de sintaxis: falta '';'' antes de ''*''
  • error C4430: especificador de tipo faltante - int asumido. Nota: C ++ no es compatible con default-int
  • error C4430: especificador de tipo faltante - int asumido. Nota: C ++ no es compatible con default-int

  • mesh.h (11): error C2653: ''MeshList'': no ​​es un nombre de clase o nombre de espacio de nombres

  • meshlist.cpp (5): error C2248: ''Mesh :: vboHandle_'': no ​​se puede acceder al miembro privado declarado en la clase ''Mesh''
  • mesh.h (10): ver la declaración de ''Mesh :: vboHandle_''
  • mesh.h (8): ver la declaración de ''Mesh''
  • meshlist.cpp (5): error C2100: indirección ilegal

Es porque ha #include "MeshList.h" en el archivo Mesh.h , por lo que el archivo MeshList.h se compilará primero, y la clase Mesh aún no se ha declarado. Para eso, el compilador pensará que Mesh en la línea de error es un nombre de variable que no tiene un tipo anterior, de ahí el error.

Este es un ejemplo de hacer una función de miembro friend :

#include <iostream> class foo; class bar { public: void barfunc(foo &f); }; class foo { private: friend void bar::barfunc(foo &f); int i; public: foo() { i = 0; } void printi() { std::cout << i << ''/n''; } }; void bar::barfunc(foo &f) { f.i = 5; } int main() { foo f; bar b; b.barfunc(f); f.printi(); return 0; }


Las dependencias cíclicas se explican en las otras respuestas ...

Aquí viene la solución:

En MeshList.h :

  • reemplace #include "Mesh.h" con la class Mesh; declaración directa class Mesh; (No necesita incluir aquí porque solo declara un puntero a una Malla)

En MeshList.cpp :

  • agregue #include "Mesh.h" a sus #include "Mesh.h" (necesita la declaración, porque usa Malla)

El último error de compilación que mencionas es otro problema:

*mesh->vboHandle_ = 4;

mesh es un puntero. Su código selecciona al miembro vboHandle_ e intenta desreferenciarlo (lo que falla). Supongo que te refieres a:

mesh->vboHandle_ = 4; // <-- no leading asterisk


El problema: dependencias cíclicas en tu incluye. El mensaje de error es menos que ideal, desafortunadamente.

La solución: si te haces amigo de toda la clase, en lugar de una sola función, puedes usar una declaración directa de la clase para romper el ciclo.

// Mesh.h #ifndef _MESH_H #define _MESH_H #include <iostream> class MeshList; class Mesh { private: unsigned int vboHandle_; friend class MeshList; public: inline void Out() {std::cout << vboHandle_;} }; #endif

Algunas pautas (subjetivas):

  • Incluya cosas en orden inverso a su capacidad para cambiarlo si se rompe, es decir: STL primero, encabezados de terceros en segundo lugar, su propio stack de middleware tercero, el proyecto actual incluye el cuarto y la biblioteca actual incluye el quinto. De esta forma, si hay un conflicto, con suerte el error apuntará a un encabezado tuyo.

  • Coloque el material public antes de las cosas private en una clase. Los clientes de la clase solo se preocupan por la interfaz pública, no es necesario que revisen todos los detalles sucios de la implementación para poder acceder a ella.