Erro com Includes - C++

Fala rapaziada, tudo bom?
Estou implementando em c++ estruturas de dados, lista, pilha, fila, lista circular e por aí vai.
Estou com um seguinte problema, criei um arquivo node.h que representa os nós de todas as minhas estruturas, e depois saio incluindo nos .h das estruturas o node.
porém eu caio no problema de redefinição quando no main eu dou include em por exemplo:

#include "lista.h" #include "stack.h"

obviamente é pq dentro de cada um estou incluindo o "node.h"
como posso fugir disso?
tentei usar clausulas do tipo #ifndef mas não está dando jogo, tentei assim:

#ifndef no #define no 1 #include "node.h" #endif

Vou mandar o começo de alguns .h que eu tenho para vcs olharem como está agora:

stack.h

#include "node.h"

class stack {...}

lista.h

#include "node.h"

class lista{...}

main.cpp - (incluindo mais de uma estrutura tudo desmorona… )

//#include "lista.h"
//#include "stack.h"    
//#include "listaCirc.h"
#include "fila.h"
#define SAIR 10

alguma luz?

obrigado!

  1. Sempre trate com #ifs todos os seus arquivos .hpp (ou .h). Exemplo:

#if !defined(__NODE_H__) #define __NODE_H__ // Seu .h aqui #endif

O jeito C de fazer a mesma coisa é assim:

#ifndef __NODE_H__ #define __NODE_H__ // Seu .h aqui #endif

  1. Se tiver referências circulares, simplesmente faça a declaração no .h de uma das classes, a que só usa ponteiros para a outra. E faça a inclusão do .h apenas no arquivo .cpp. Exemplo:

Arquivo lista.h

#if !defined(__LISTA_H__)
#define __LISTA_H__

class Node;

public class Lista {
   private:
      Node* cabeca;

   //Outros métodos
};
#endif

Arquivo lista.cpp

[code]#include “Node.h”

Lista::Lista() {
//Construtor
}


[/code]

Lembre-se que em C++ definition e declaration são coisas diferentes.

Note que o ifndef fica no arquivo .h e não no cpp. É uma instrução para o compilador: “Se vc ainda não leu esse .h, leia-o e marque como lido. Se já leu, ignore.”

Perfeito!

Muito obrigado!

outro modo que encontrei foi fazer uso da diretiva #pragma once

#pragma once
#include <string>
using namespace std;

// Definição da classe node
class node {...}

Um abraço!

Só cuidado que nem todos os compiladores entendem essa diretiva.

Na verdade, #pragma é a diretiva para se dar um comando específico de compilador ou plataforma:
http://msdn.microsoft.com/en-us/library/d9x1s805(v=vs.80).aspx