C++ error: Invalid use of incomplete type ... 
<p>I have a small- to medium-size project that I am doing for my software engineering course this semester. I have chosen to do it in C++ (gtkmm). I am doing okay so far but I have run into a problem with circular references or the following errors:</p>

<pre><code>Login_Dialog.cpp:25: error: invalid use of incomplete type ‘struct MainWindow’
Login_Dialog.h:12: error: forward declaration of ‘struct MainWindow’
make: *** [Login_Dialog.o] Error 1
</code></pre>

<p>In short I have about 10 classes and I know in the future they are all going to need to talk to each other. I have run into one specific case so far, and I have been trying to resolve it on my own, but I am totally stuck.</p>

<p>My program has a main window class that is defined as follows:</p>

<pre><code>/*
 * MainWindow.h
 */

#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_

#include "includes.h"

#include "ModelDrawing.h"
#include "ViewDrawing.h"
#include "ControlerDrawing.h"
#include "ModelChat.h"
#include "ViewChat.h"
#include "ControlerChat.h"
#include "ModelQueue.h"
#include "ViewQueue.h"
#include "ControlerQueue.h"
#include "Login_Dialog.h"
#include "TCP_IP_Socket.h"

class MainWindow : public Window
{
public:
 MainWindow(int type);
 ~MainWindow();

 void on_menu_file_new_generic();
 void on_menu_file_quit();

 ModelDrawing* get_mdl_Draw();
 ViewDrawing* get_view_Draw();
 ControlerDrawing* get_cntrl_Draw();

 ModelChat* get_mdl_Chat();
 ViewChat* get_view_Chat();
 ControlerChat* get_cntrl_Chat();

 ModelQueue* get_mdl_Que();
 ViewQueue* get_view_Que();
 ControlerQueue* get_cntrl_Que();

 Label* get_status_label();

 void set_status_label(Glib::ustring label);

 TCP_IP_Socket* get_socket();

private:
 TCP_IP_Socket* socket;

 Widget* menu;
 RefPtr&lt;Gtk::ActionGroup&gt; m_refActionGroup;
 RefPtr&lt;Gtk::UIManager&gt; m_refUIManager;

 ModelDrawing* mdl_Draw;
 ViewDrawing* view_Draw;
 ControlerDrawing* cntrl_Draw;

 ModelChat* mdl_Chat;
 ViewChat* view_Chat;
 ControlerChat* cntrl_Chat;

 ModelQueue* mdl_Que;
 ViewQueue* view_Que;
 ControlerQueue* cntrl_Que;

 Frame* label_frame;
 Label* status_label;

 Login_Dialog* login;
protected:
 //Containers
 HBox* main_HBox;
 VBox* base_VBox;
};

#endif /* MAINWINDOW_H_ */
</code></pre>

<p>The functions are defined as follows:</p>

<pre><code>/*
 * MainWindow.cpp
 */

#include "MainWindow.h"

MainWindow::MainWindow(int type)
{
 this-&gt;socket = new TCP_IP_Socket(this);

 //Login Section
 this-&gt;login = new Login_Dialog(WINDOW_TOPLEVEL, this);
 int status;
 status = this-&gt;login-&gt;run();
 if(status == 0)
 {
  exit(1);
 }
 this-&gt;login-&gt;hide();

 //By Default Create and Open Up Student Queue
 this-&gt;mdl_Que = new ModelQueue(this);
 this-&gt;view_Que = new ViewQueue(this);
 this-&gt;cntrl_Que = new ControlerQueue(this, (this-&gt;mdl_Que), (this-&gt;view_Que));

 this-&gt;set_default_size(1200, 750);
 this-&gt;set_border_width(1);
 this-&gt;set_title("Tutor App");

 this-&gt;base_VBox = manage(new VBox());
 this-&gt;main_HBox = manage(new HBox());
 this-&gt;label_frame = manage(new Frame());

 m_refActionGroup = Gtk::ActionGroup::create();
 m_refUIManager = Gtk::UIManager::create();
 m_refActionGroup-&gt;add(Gtk::Action::create("FileMenu", "File"));
 this-&gt;add_accel_group(m_refUIManager-&gt;get_accel_group());
 Glib::ustring ui_info =
 "&lt;ui&gt;"
 "&lt;menubar name='MenuBar'&gt;"
 " &lt;menu action='FileMenu'&gt;"
 " &lt;/menu&gt;"
 "&lt;/menubar&gt;"
 "&lt;/ui&gt;";
 m_refUIManager-&gt;insert_action_group(m_refActionGroup);
 m_refUIManager-&gt;add_ui_from_string(ui_info);
 this-&gt;menu = m_refUIManager-&gt;get_widget("/MenuBar");

 this-&gt;mdl_Draw = new ModelDrawing(this);
 this-&gt;view_Draw = new ViewDrawing(this);
 this-&gt;cntrl_Draw = new ControlerDrawing(this, (this-&gt;mdl_Draw), (this-&gt;view_Draw));

 this-&gt;mdl_Chat = new ModelChat(this);
 this-&gt;view_Chat = new ViewChat(this);
 this-&gt;cntrl_Chat = new ControlerChat(this, (this-&gt;mdl_Chat), (this-&gt;view_Chat));

 this-&gt;status_label = manage(new Label("Welcome to The Tutor App", ALIGN_LEFT, ALIGN_LEFT, false));

 //Put it all together
 this-&gt;main_HBox-&gt;pack_start(*(this-&gt;view_Draw-&gt;get_left_VBox()));
 this-&gt;label_frame-&gt;add(*(this-&gt;status_label));
 this-&gt;base_VBox-&gt;pack_end(*(this-&gt;label_frame));
 this-&gt;main_HBox-&gt;pack_end(*(this-&gt;view_Chat-&gt;get_right_VBox()));
 this-&gt;base_VBox-&gt;pack_start(*(this-&gt;menu), Gtk::PACK_SHRINK);
 this-&gt;base_VBox-&gt;pack_end(*(this-&gt;main_HBox), true, true);

 this-&gt;label_frame-&gt;set_size_request(-1, 5);

 this-&gt;add(*(this-&gt;base_VBox));
 this-&gt;show_all();
 this-&gt;view_Que-&gt;get_window()-&gt;show_all();
}

MainWindow::~MainWindow()
{
}

ModelDrawing* MainWindow::get_mdl_Draw()
{
 return NULL;
}

ViewDrawing* MainWindow::get_view_Draw()
{
 return NULL;
}

ControlerDrawing* MainWindow::get_cntrl_Draw()
{
 return NULL;
}

ModelChat* MainWindow::get_mdl_Chat()
{
 return NULL;
}

ViewChat* MainWindow::get_view_Chat()
{
 return NULL;
}

ControlerChat* MainWindow::get_cntrl_Chat()
{
 return NULL;
}

ModelQueue* MainWindow::get_mdl_Que()
{
 return NULL;
}

ViewQueue* MainWindow::get_view_Que()
{
 return this-&gt;view_Que;
}

ControlerQueue* MainWindow::get_cntrl_Que()
{
 return NULL;
}

Label* MainWindow::get_status_label()
{
 return this-&gt;status_label;
}

void MainWindow::set_status_label(Glib::ustring label)
{
 this-&gt;status_label-&gt;set_label(label);
}

TCP_IP_Socket* MainWindow::get_socket()
{
    return this-&gt;socket;
}

void MainWindow::on_menu_file_quit()
{
 hide(); //Closes the main window to stop the Gtk::Main::run().
}

void MainWindow::on_menu_file_new_generic()
{
   std::cout &lt;&lt; "A File|New menu item was selected." &lt;&lt; std::endl;
}
</code></pre>

<p>Now the main window creates a <code>TCP_IP_Socket</code> class and a login dialog. I first create the connection and set a few strings (seen in the code below):</p>

<pre><code>/*
 *  TCP_IP_Socket.cpp
 */

#include "TCP_IP_Socket.h"

TCP_IP_Socket::TCP_IP_Socket(MainWindow* hwnd)
{
 this-&gt;hwnd = hwnd;

    server_name = "www.geoginfo.com";
    this-&gt;set_server_ustring(this-&gt;server_name);
    printf("%s", this-&gt;server_name);

 struct addrinfo specs;
 struct addrinfo* results;
 int status;

 memset(&amp;specs, 0, sizeof specs);
 specs.ai_flags = 0;
 specs.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
 specs.ai_socktype = SOCK_STREAM;

 if ((status = getaddrinfo(this-&gt;server_name, NULL, &amp;specs, &amp;results)) != 0)
 {
  fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
  exit(0);
 }

    char ipstr[INET6_ADDRSTRLEN];
 void* addr;
    if (results-&gt;ai_family == AF_INET)
 { // IPv4
  struct sockaddr_in* ipv4 = (struct sockaddr_in*)results-&gt;ai_addr;
  addr = &amp;(ipv4-&gt;sin_addr);
 }
 else
 { // IPv6
  struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)results-&gt;ai_addr;
  addr = &amp;(ipv6-&gt;sin6_addr);
 }
 inet_ntop(results-&gt;ai_family, addr, ipstr, sizeof ipstr);
 this-&gt;set_serverip_ustring(ipstr);
 printf(" = %s\n", ipstr);
 freeaddrinfo(results); // free the linked list
 printf("\n");
}


TCP_IP_Socket::~TCP_IP_Socket()
{
}

void TCP_IP_Socket::set_server_ustring(const char* server_name)
{
    this-&gt;server_domainname = new ustring(server_name);
}

void TCP_IP_Socket::set_serverip_ustring(const char* ip)
{
    this-&gt;server_ip = new ustring(ip);
}

Glib::ustring* TCP_IP_Socket::get_server_domainname()
{
    return this-&gt;server_domainname;
}

Glib::ustring* TCP_IP_Socket::get_server_ip()
{
    return this-&gt;server_ip;
}
</code></pre>

<p>and then I create the login and try to access the <code>server_ip</code> ustring and <code>server_domainname</code> ustring from my login dialog:</p>

<pre><code>/*
 * Login_Dialog.cpp
 */

#include "Login_Dialog.h"

Login_Dialog::Login_Dialog(int type, MainWindow* hwnd)
{
 this-&gt;hwnd = hwnd;
 this-&gt;set_default_size(100, 150);

 this-&gt;user_layout = manage(new HBox());
 this-&gt;pswd_layout = manage(new HBox());

 this-&gt;user_name = manage(new Label("Username"));
 this-&gt;user_entry = manage(new Entry());
 this-&gt;pswd_user = manage(new Label("Password"));
 this-&gt;pswd_entry = manage(new Entry());
 this-&gt;Ok = add_button("Ok", 1);
 this-&gt;Cancel = add_button("Cancel", 0);

 Glib::ustring* one = hwnd-&gt;get_socket()-&gt;get_server_domainname();
 this-&gt;status_label = manage (new Label("This is a test", ALIGN_LEFT, ALIGN_LEFT, false));

 this-&gt;Ok-&gt;set_size_request(74, -1);
 this-&gt;Cancel-&gt;set_size_request(74, -1);

 this-&gt;user_layout-&gt;pack_start(*(this-&gt;user_name), true, true);
 this-&gt;user_layout-&gt;pack_end(*(this-&gt;user_entry), true, true);
 this-&gt;pswd_layout-&gt;pack_start(*(this-&gt;pswd_user), true, true);
 this-&gt;pswd_layout-&gt;pack_end(*(this-&gt;pswd_entry), true, true);
 this-&gt;get_vbox()-&gt;pack_start(*(this-&gt;user_layout));
 this-&gt;get_vbox()-&gt;pack_end(*(this-&gt;status_label), true, true);
 this-&gt;get_vbox()-&gt;pack_end(*(this-&gt;pswd_layout));

 show_all(); //&lt;-- This is key
}

void Login_Dialog::set_status_label(Glib::ustring label)
{
 this-&gt;status_label-&gt;set_label(label);
}
</code></pre>

<p>When I try to compile this I get the error listed at the very top of this post. If I remove <code>class MainWindow;</code> and replace it with <code>#include "MainWindow.h"</code>, I run into circular reference issues with headers. </p>

<p>I know I posted a lot of code, but I didn't want to get flamed for not posting enough.</p>
