2010-03-06 15 views
6

मेरे पास एक छोटा-से मध्यम आकार का प्रोजेक्ट है जो मैं इस सेमेस्टर में अपने सॉफ्टवेयर इंजीनियरिंग पाठ्यक्रम के लिए कर रहा हूं। मैंने इसे सी ++ (gtkmm) में करना चुना है। मैं ठीक अब तक कर रहा हूँ, लेकिन मैं वृत्तीय संदर्भ या निम्न त्रुटियों के साथ एक समस्या में पड़ गए हैं:सी ++ त्रुटि: अपूर्ण प्रकार का अमान्य उपयोग ...

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 

संक्षेप में मैं के बारे में 10 वर्गों है और मैं जानता हूँ कि भविष्य में वे सब करने के लिए बात करने की आवश्यकता करने जा रहे हैं एक दूसरे। मैंने अभी तक एक विशिष्ट मामले में भाग लिया है, और मैं इसे अपने आप हल करने की कोशिश कर रहा हूं, लेकिन मैं पूरी तरह से अटक गया हूं।

/* 
* 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; 
} 

अब मुख्य विंडो एक TCP_IP_Socket वर्ग और एक लॉगिन संवाद बनाता है:

/* 
* 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_ */ 

कार्यों के रूप में निम्नानुसार परिभाषित कर रहे हैं:

मेरे कार्यक्रम एक मुख्य विंडो वर्ग कि परिभाषित किया गया है इस प्रकार है । मैं पहली बार कनेक्शन बनाने और कुछ तार (नीचे दिए गए कोड में देखा) सेट:

/* 
* 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; 
} 

और फिर मैं लॉगिन बनाने और server_ip ustring और server_domainname अपना लॉगिन संवाद से ustring तक पहुँचने का प्रयास:

/* 
* 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); 
} 

जब मैं इसे संकलित करने का प्रयास करता हूं तो मुझे इस पोस्ट के शीर्ष पर सूचीबद्ध त्रुटि मिलती है। अगर मैं class MainWindow; हटा देता हूं और इसे #include "MainWindow.h" से प्रतिस्थापित करता हूं, तो मैं हेडर के साथ परिपत्र संदर्भ समस्याओं में भाग लेता हूं।

मुझे पता है कि मैंने बहुत सारे कोड पोस्ट किए हैं, लेकिन मैं पर्याप्त पोस्ट न करने के लिए फ्लेमड नहीं करना चाहता था।

+7

आपने बहुत सी कोड पोस्ट की हैं, लेकिन महत्वपूर्ण एक को याद किया .. Login_Dialog।एच – Naveen

उत्तर

15

आप लॉग इन_Dialog.h में मेनविंडो को आगे घोषित कर सकते हैं जब तक कि आप केवल उस प्रकार के पॉइंटर को घोषित करते हैं (जो आप करते हैं), और आप इसे Login_Dialog.h के शीर्ष पर जोड़ते हैं ताकि संकलक से अपेक्षा की जा सके कुछ समय बाद कक्षा घोषणा देखें।

class MainWindow; 

फिर login_Dialog.cpp में, इस तरह "mainwindow.h" शामिल करें।

/* 
* Login_Dialog.cpp 
* 
* Created on: Mar 2, 2010 
*  Author: Matthew 
*/ 

#include "Login_Dialog.h" 
#include "MainWindow.h" 

ऐसा करना चाहिए।

+2

+1 एक और अधिक विशिष्ट - और समझने में आसान - यह कहने का तरीका कि मैं क्या कोशिश कर रहा था (और असफल) कहने के लिए: पी –

1

When I try and do this I get the error presented at the very top of this post. If I try and remove the class MainWindow; and replace it with #include "MainWindow.h" I run into circular reference issues with headers.

लेकिन यह मुद्दा है। आपको कार्यान्वयन को एक अलग कार्यान्वयन (.cpp) फ़ाइल में स्थानांतरित करने की आवश्यकता है। आप शीर्षलेख फ़ाइलों में परिपत्र संदर्भों को तोड़ने के लिए आगे की घोषणाओं का उपयोग कर सकते हैं, लेकिन आपके प्रकार का उपयोग करने का प्रयास करने से पहले आपको दोनों शीर्षलेख उपलब्ध होना चाहिए।

आपको इसका उपयोग करने से पहले आपको कक्षा की पूरी परिभाषा शामिल करनी होगी - न कि केवल एक आगे की घोषणा। अग्रेषित घोषणाएं अन्य अग्रेषित घोषणाओं के लिए केवल उपयोगी हैं - संकलक को यह पता होना चाहिए कि यह कोड उत्पन्न करने से पहले किस प्रकार काम कर रहा है।

0

मेन_विंडो.h में Login_Dialog क्लास की आगे की घोषणा के साथ आपको #include "Login_Dialog.h" को प्रतिस्थापित करने के लिए त्रुटि को ठीक करने के लिए। फिर Login_Dialog.cpp में Main_Window.cpp और Main_Window.h में Login_Dialog.h शामिल करें। बीटीडब्ल्यू, यह कई अन्य फाइलों/वर्गों के लिए भी किया जा सकता है।

संबंधित मुद्दे