C++ error: Invalid use of incomplete type ...

Habe ich eine kleine bis mittelgroße Projekt, das Tue ich für meine software-engineering-Kurs in diesem semester. Ich habe entschieden, es zu tun in C++ (gtkmm). Ich Tue, okay so weit, aber ich habe ein problem mit zirkulären Referenzen oder die folgenden Fehler:

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

Kurz gesagt, ich habe über 10 Klassen und ich weiß, in der Zukunft werden Sie alle gehen zu müssen, um miteinander zu reden. Ich habe laufen in einem konkreten Fall so weit, und ich habe versucht, es zu beheben, auf meiner eigenen, aber ich bin völlig stecken.

Mein Programm hat ein Hauptfenster-Klasse, die wie folgt definiert ist:

/*
 * 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<Gtk::ActionGroup> m_refActionGroup;
 RefPtr<Gtk::UIManager> 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_ */

Die Funktionen sind wie folgt definiert:

/*
 * MainWindow.cpp
 */

#include "MainWindow.h"

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

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

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

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

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

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

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

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

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

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

 this->label_frame->set_size_request(-1, 5);

 this->add(*(this->base_VBox));
 this->show_all();
 this->view_Que->get_window()->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->view_Que;
}

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

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

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

TCP_IP_Socket* MainWindow::get_socket()
{
    return this->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 << "A File|New menu item was selected." << std::endl;
}

Nun das Hauptfenster erstellt eine TCP_IP_Socket Klasse und ein login-dialog. Ich zuerst erstellen Sie die Verbindung und legen Sie ein paar strings (gesehen im code unten):

/*
 *  TCP_IP_Socket.cpp
 */

#include "TCP_IP_Socket.h"

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

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

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

 memset(&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->server_name, NULL, &specs, &results)) != 0)
 {
  fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
  exit(0);
 }

    char ipstr[INET6_ADDRSTRLEN];
 void* addr;
    if (results->ai_family == AF_INET)
 { //IPv4
  struct sockaddr_in* ipv4 = (struct sockaddr_in*)results->ai_addr;
  addr = &(ipv4->sin_addr);
 }
 else
 { //IPv6
  struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)results->ai_addr;
  addr = &(ipv6->sin6_addr);
 }
 inet_ntop(results->ai_family, addr, ipstr, sizeof ipstr);
 this->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->server_domainname = new ustring(server_name);
}

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

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

Glib::ustring* TCP_IP_Socket::get_server_ip()
{
    return this->server_ip;
}

und dann erstelle ich den login und Zugriff auf den server_ip ustring und server_domainname ustring von meinem login-dialog:

/*
 * Login_Dialog.cpp
 */

#include "Login_Dialog.h"

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

 this->user_layout = manage(new HBox());
 this->pswd_layout = manage(new HBox());

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

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

 this->Ok->set_size_request(74, -1);
 this->Cancel->set_size_request(74, -1);

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

 show_all(); //<-- This is key
}

void Login_Dialog::set_status_label(Glib::ustring label)
{
 this->status_label->set_label(label);
}

Wenn ich versuche zu kompilieren, dies bekomme ich die Fehlermeldung, aufgeführt an der Spitze von diesem post. Wenn ich entfernen class MainWindow; und ersetzen Sie es mit #include "MainWindow.h", ich starte in Zirkelbezug Probleme mit Header.

Ich weiß, ich habe eine Menge code, aber ich wollte nicht geflamed für die Buchung nicht genug.

Sie veröffentlicht viel code , verpasste aber den entscheidenden.. Login_Dialog.h

InformationsquelleAutor Matthew Hoggan | 2010-03-06

Schreibe einen Kommentar