CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Oct 2016
    Posts
    22

    Forward declaration is not working

    Hello . I'm working on C++/CLI app and I'm having problems with forward declaration. I was reading how compiler works and everything and I still don't get it. Here is my code:

    Search.h:

    Code:
    #pragma once
    
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    
    namespace SMSALENalozi {
    
    	/// <summary>
    	/// Summary for Search
    	/// </summary>
    	public ref class Search : public System::Windows::Forms::UserControl
    	{
    	public:
    		Search(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Add the constructor code here
    			trazi_label->Parent = search_background_picturebox;
    			searchby_combobox->SelectedIndex = 0;
    			//
    		}
    
    	protected:
    		/// <summary>
    		/// Clean up any resources being used.
    		/// </summary>
    		~Search()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    	private: System::Windows::Forms::PictureBox^  search_background_picturebox;
    	protected:
    
    	private: System::Windows::Forms::Label^  trazi_label;
    	private: System::Windows::Forms::TextBox^  accountwriting_textbox;
    	private: System::Windows::Forms::ComboBox^  searchby_combobox;
    
    
    	protected:
    
    	private:
    		/// <summary>
    		/// Required designer variable.
    		Control^ window_control;
    		/// </summary>
    		System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Search::typeid));
    			this->search_background_picturebox = (gcnew System::Windows::Forms::PictureBox());
    			this->trazi_label = (gcnew System::Windows::Forms::Label());
    			this->accountwriting_textbox = (gcnew System::Windows::Forms::TextBox());
    			this->searchby_combobox = (gcnew System::Windows::Forms::ComboBox());
    			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->search_background_picturebox))->BeginInit();
    			this->SuspendLayout();
    			// 
    			// search_background_picturebox
    			// 
    			this->search_background_picturebox->Image = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"search_background_picturebox.Image")));
    			this->search_background_picturebox->Location = System::Drawing::Point(0, 0);
    			this->search_background_picturebox->Name = L"search_background_picturebox";
    			this->search_background_picturebox->Size = System::Drawing::Size(884, 561);
    			this->search_background_picturebox->SizeMode = System::Windows::Forms::PictureBoxSizeMode::AutoSize;
    			this->search_background_picturebox->TabIndex = 0;
    			this->search_background_picturebox->TabStop = false;
    			// 
    			// trazi_label
    			// 
    			this->trazi_label->AutoSize = true;
    			this->trazi_label->BackColor = System::Drawing::Color::Transparent;
    			this->trazi_label->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 24, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
    				static_cast<System::Byte>(0)));
    			this->trazi_label->ForeColor = System::Drawing::Color::White;
    			this->trazi_label->Location = System::Drawing::Point(399, 198);
    			this->trazi_label->Name = L"trazi_label";
    			this->trazi_label->Size = System::Drawing::Size(87, 37);
    			this->trazi_label->TabIndex = 0;
    			this->trazi_label->Text = L"traži:";
    			// 
    			// accountwriting_textbox
    			// 
    			this->accountwriting_textbox->AutoCompleteCustomSource->AddRange(gcnew cli::array< System::String^  >(4) {
    				L"FILIP", L"STEFAN",
    					L"SALE", L"SLADJA"
    			});
    			this->accountwriting_textbox->AutoCompleteMode = System::Windows::Forms::AutoCompleteMode::Suggest;
    			this->accountwriting_textbox->AutoCompleteSource = System::Windows::Forms::AutoCompleteSource::CustomSource;
    			this->accountwriting_textbox->Location = System::Drawing::Point(334, 270);
    			this->accountwriting_textbox->Name = L"accountwriting_textbox";
    			this->accountwriting_textbox->Size = System::Drawing::Size(216, 20);
    			this->accountwriting_textbox->TabIndex = 1;
    			this->accountwriting_textbox->PreviewKeyDown += gcnew System::Windows::Forms::PreviewKeyDownEventHandler(this, &Search::accountwriting_textbox_PreviewKeyDown);
    			// 
    			// searchby_combobox
    			// 
    			this->searchby_combobox->DropDownStyle = System::Windows::Forms::ComboBoxStyle::DropDownList;
    			this->searchby_combobox->FormattingEnabled = true;
    			this->searchby_combobox->Items->AddRange(gcnew cli::array< System::Object^  >(4) { L"TABLICA", L"AUTO", L"PREZIME", L"IME" });
    			this->searchby_combobox->Location = System::Drawing::Point(558, 270);
    			this->searchby_combobox->Name = L"searchby_combobox";
    			this->searchby_combobox->Size = System::Drawing::Size(90, 21);
    			this->searchby_combobox->TabIndex = 2;
    			// 
    			// Search
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->Controls->Add(this->searchby_combobox);
    			this->Controls->Add(this->accountwriting_textbox);
    			this->Controls->Add(this->trazi_label);
    			this->Controls->Add(this->search_background_picturebox);
    			this->Name = L"Search";
    			this->Size = System::Drawing::Size(884, 561);
    			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->search_background_picturebox))->EndInit();
    			this->ResumeLayout(false);
    			this->PerformLayout();
    
    		}
    #pragma endregion
    	private: System::Void accountwriting_textbox_PreviewKeyDown(System::Object^  sender, System::Windows::Forms::PreviewKeyDownEventArgs^  e) {
    
    		if (e->KeyCode == Keys::Enter) {
    
    			this->Hide();
    
    		}
    
    	}
    };
    }
    Window.h:

    Code:
    #pragma once
    
    namespace SMSALENalozi {
    
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    
    	ref class ProgramItems; //forward declaration
    
    	/// <summary>
    	/// Summary for Window
    	/// </summary>
    	public ref class Window : public System::Windows::Forms::Form
    	{
    	public:
    		Window()
    		{
    			InitializeComponent();
    			//
    			//TODO: Add the constructor code here
    			//
    		}
    
    	protected:
    		/// <summary>
    		/// Clean up any resources being used.
    		/// </summary>
    		~Window()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    	private: System::Windows::Forms::PictureBox^  menu_background_picturebox;
    	private: System::Windows::Forms::PictureBox^  logo_picturebox;
    	private: System::Windows::Forms::Label^  ulogujse_label;
    	private: System::Windows::Forms::TextBox^  passwordwriting_textbox;
    	private: System::Windows::Forms::Button^  ulogujse_button;
    
    
    	protected:
    
    	protected:
    
    
    
    	protected:
    
    	protected:
    
    	private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    		System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Window::typeid));
    			this->menu_background_picturebox = (gcnew System::Windows::Forms::PictureBox());
    			this->logo_picturebox = (gcnew System::Windows::Forms::PictureBox());
    			this->ulogujse_label = (gcnew System::Windows::Forms::Label());
    			this->passwordwriting_textbox = (gcnew System::Windows::Forms::TextBox());
    			this->ulogujse_button = (gcnew System::Windows::Forms::Button());
    			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->menu_background_picturebox))->BeginInit();
    			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->logo_picturebox))->BeginInit();
    			this->SuspendLayout();
    			// 
    			// menu_background_picturebox
    			// 
    			this->menu_background_picturebox->Image = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"menu_background_picturebox.Image")));
    			this->menu_background_picturebox->Location = System::Drawing::Point(0, 0);
    			this->menu_background_picturebox->Name = L"menu_background_picturebox";
    			this->menu_background_picturebox->Size = System::Drawing::Size(884, 561);
    			this->menu_background_picturebox->SizeMode = System::Windows::Forms::PictureBoxSizeMode::AutoSize;
    			this->menu_background_picturebox->TabIndex = 0;
    			this->menu_background_picturebox->TabStop = false;
    			// 
    			// logo_picturebox
    			// 
    			this->logo_picturebox->BackColor = System::Drawing::Color::Transparent;
    			this->logo_picturebox->Image = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"logo_picturebox.Image")));
    			this->logo_picturebox->Location = System::Drawing::Point(269, 108);
    			this->logo_picturebox->Name = L"logo_picturebox";
    			this->logo_picturebox->Size = System::Drawing::Size(346, 206);
    			this->logo_picturebox->SizeMode = System::Windows::Forms::PictureBoxSizeMode::AutoSize;
    			this->logo_picturebox->TabIndex = 1;
    			this->logo_picturebox->TabStop = false;
    			// 
    			// ulogujse_label
    			// 
    			this->ulogujse_label->AutoSize = true;
    			this->ulogujse_label->BackColor = System::Drawing::Color::Transparent;
    			this->ulogujse_label->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 15.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point,
    				static_cast<System::Byte>(0)));
    			this->ulogujse_label->ForeColor = System::Drawing::Color::White;
    			this->ulogujse_label->Location = System::Drawing::Point(390, 414);
    			this->ulogujse_label->Name = L"ulogujse_label";
    			this->ulogujse_label->Size = System::Drawing::Size(105, 25);
    			this->ulogujse_label->TabIndex = 2;
    			this->ulogujse_label->Text = L"uloguj se:";
    			// 
    			// passwordwriting_textbox
    			// 
    			this->passwordwriting_textbox->Location = System::Drawing::Point(334, 450);
    			this->passwordwriting_textbox->Name = L"passwordwriting_textbox";
    			this->passwordwriting_textbox->Size = System::Drawing::Size(216, 20);
    			this->passwordwriting_textbox->TabIndex = 3;
    			this->passwordwriting_textbox->UseSystemPasswordChar = true;
    			this->passwordwriting_textbox->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Window::passwordwriting_textbox_KeyPress);
    			// 
    			// ulogujse_button
    			// 
    			this->ulogujse_button->Location = System::Drawing::Point(406, 486);
    			this->ulogujse_button->Name = L"ulogujse_button";
    			this->ulogujse_button->Size = System::Drawing::Size(72, 36);
    			this->ulogujse_button->TabIndex = 4;
    			this->ulogujse_button->Text = L"uloguj se";
    			this->ulogujse_button->UseVisualStyleBackColor = true;
    			// 
    			// Window
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->BackColor = System::Drawing::Color::White;
    			this->ClientSize = System::Drawing::Size(884, 561);
    			this->Controls->Add(this->ulogujse_button);
    			this->Controls->Add(this->passwordwriting_textbox);
    			this->Controls->Add(this->ulogujse_label);
    			this->Controls->Add(this->logo_picturebox);
    			this->Controls->Add(this->menu_background_picturebox);
    			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
    			this->MaximizeBox = false;
    			this->Name = L"SMSALENalozi";
    			this->Text = L"SMSALE Nalozi";
    			this->Load += gcnew System::EventHandler(this, &Window::Window_Load);
    			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->menu_background_picturebox))->EndInit();
    			(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->logo_picturebox))->EndInit();
    			this->ResumeLayout(false);
    			this->PerformLayout();
    
    		}
    #pragma endregion
    	private: System::Void Window_Load(System::Object^  sender, System::EventArgs^  e) {
    
    		logo_picturebox->Parent = menu_background_picturebox;
    
    		ulogujse_label->Parent = menu_background_picturebox;
    
    	}
    	private: System::Void passwordwriting_textbox_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) {
    
    		if (e->KeyChar == (char)13) {
    
    			if (passwordwriting_textbox->Text == "KRASTA") {
    
    				ProgramItems::test; //makes error every time I add this. LINE 167
    
    				Search ^s = gcnew Search();
    
    				this->Controls->Clear();
    
    				this->Controls->Add(s);
    
    			}
    
    		}
    
    	}
    };
    }
    Program.h:

    Code:
    #pragma once
    
    #include "Search.h"
    #include "Window.h"
    
    namespace SMSALENalozi {
    
    	ref class ProgramItems {
    
    	public:
    
    		static int test;
    
    		static SMSALENalozi::Window ^window;
    
    		static SMSALENalozi::Search ^search;
    
    	};
    
    }
    Program.cpp (start point):

    Code:
    #include "Program.h"
    
    using namespace System;
    using namespace System::Windows::Forms;
    
    [STAThread]
    int main() {
    
    	Application::EnableVisualStyles();
    	
    	Application::SetCompatibleTextRenderingDefault(false);
    
    	SMSALENalozi::ProgramItems::search = gcnew SMSALENalozi::Search();
    
    	SMSALENalozi::ProgramItems::window = gcnew SMSALENalozi::Window();
    
    	Application::Run(SMSALENalozi::ProgramItems::window);
    
    	return 0;
    }
    and the errors are:
    C2027 use of undefined type 'SMSALENalozi::ProgramItems' File: Window.h

    C2065 'test': undeclared identifier File: Window.h

    Thanks .

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Forward declaration is not working

    When the compiler processes Window.h, it knows, by the forward declaration, that a class named ProgramItems exists, but not which members it has, hence the error message. You must #include a file containing the complete class definition, as you have it in Program.h, at the beginning of Window.h to get rid of the error. The forward declaration is superfluous then and can be removed.

    Should the class ProgramItems define any methods, only their prototypes need to be known at that point. Their actual implementation can (and should, following standard C++ coding practices) reside in a separate .cpp file. Should they be missing, then, you'd get a linker error.

    BTW, doesn't the forward declaration mess up the Forms Designer? As I recall it, the Form class needs to be the only (or at least first) class in the .h file for the Designer to work correctly. Any other classes, including forward declarations, need to reside in separate .h files you include. However, I experienced that once with VC++ 2010; they may have made the Designer more tolerant in the meantime.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Oct 2016
    Posts
    22

    Re: Forward declaration is not working

    Thanks. But I'm sorry, where should and what should I include to fix this problem? I tried #include "Program.h" in Window.h but it's not working, error says: C2065 'test': undeclared identifier and C2653 'ProgramItems': is not a class or namespace name
    Yes, you were right for forms designer mess.
    Last edited by Putarda; February 7th, 2017 at 02:23 PM.

  4. #4
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Forward declaration is not working

    Right, that's not a solution. Program.h and Window.h now include each other mutually. Without the #pragma once, this would lead to a fatal compiler (more exactly: preprocessor) error due to an infinite recursion. With the pragma, the content of Program.h included in Window.h is simply ignored.

    A solution would be to remove the class definition (i.e. anything but the three directives at the top) from Program.h. Instead, put that into a new file, say, ProgramItems.h, preceded by a #pragma once. #include that new file in Window.h and remove the forward declaration.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  5. #5
    Join Date
    Oct 2016
    Posts
    22

    Re: Forward declaration is not working

    But what happens with Program.h?
    Last edited by Putarda; February 7th, 2017 at 04:51 PM.

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Forward declaration is not working

    Well, after my proposed solution, it merely bundles the two includes. You can leave it in this state; it should work that way. Or you may discard Program.h entirely and instead include both Window.h and Search.h directly in Program.cpp, which is what I would probably do myself.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  7. #7
    Join Date
    Oct 2016
    Posts
    22

    Re: Forward declaration is not working

    I tried everything you said and it's still not working.

  8. #8
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Forward declaration is not working

    What symptoms?
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  9. #9
    Join Date
    Oct 2016
    Posts
    22

    Re: Forward declaration is not working

    This is my current code:
    Program.cpp:
    Code:
    #include "ProgramItems.h"
    #include "Search.h"
    #include "Window.h"
    
    using namespace System;
    using namespace System::Windows::Forms;
    
    [STAThread]
    int main() {
    
    	Application::EnableVisualStyles();
    	
    	Application::SetCompatibleTextRenderingDefault(false);
    
    	SMSALENalozi::ProgramItems::search = gcnew SMSALENalozi::Search();
    
    	SMSALENalozi::ProgramItems::window = gcnew SMSALENalozi::Window();
    
    	Application::Run(SMSALENalozi::ProgramItems::window);
    
    	return 0;
    }
    ProgramItems.h:
    Code:
    #pragma once
    
    //#include "Program.h"
    #include "Search.h"
    #include "Window.h"
    
    namespace SMSALENalozi {
    
    	ref class ProgramItems {
    
    	public:
    
    		//static int test = 0;
    
    		static Window ^window;
    
    		static Search ^search;
    
    	};
    
    }
    Window.h:
    Code:
    #pragma once
    
    #include "ProgramItems.h"
    ...

  10. #10
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Forward declaration is not working

    Again, you have a mutual inclusion here, which is a big no-no and must be avoided under all circumstances!

    My fault during this discussion so far was to exclusively put my focus on the ProgramItems::test member, ignoring that is also has members of type Window ^ and Search ^. This complicates the scenario considerably, however, such a scenario is not really uncommon. A common approach to such a scenario is the definition and use of interface and/or abstract classes.

    However, an important question is whether the complexity of the scenario can't be reduced up-front. The only reference to the ProgramItems class I see is to its test member. The fundamental question now is: How much, if anything at all, does the Window class really need to know about the class that holds its own instance?
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  11. #11
    Join Date
    Oct 2016
    Posts
    22

    Re: Forward declaration is not working

    No, it only needs to know about UserControls (search), so it can manage them.
    EDIT: And usercontrols about window.
    Last edited by Putarda; February 7th, 2017 at 06:00 PM.

  12. #12
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Forward declaration is not working

    OK, that's good news I think. Both of these are derived from Windows Forms framework classes which can be considered as globally known from the perspective of an application. How much of the information that needs to be exchanged between your classes can be conveyed over properties/methods of their base classes? If the answer is "everything I need", it's perfectly fine. If "everything I need" should apply to one of the classes but not the other, it shouldn't be too complicated too.

    The "trick" here is, if the info that needs to be accessed of your, let's say, Form derivate is nothing more than its screen bounds, it's enough to refer to it as a Form instance, ignoring that it actually is a derivate. (Admittedly, this example is a bit unrealistic for the sake of simplicity. I hope it explains what I mean.)
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  13. #13
    Join Date
    Oct 2016
    Posts
    22

    Re: Forward declaration is not working

    I still have a problem. But thank you very much!
    Last edited by Putarda; February 7th, 2017 at 08:33 PM.

  14. #14
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Forward declaration is not working

    Thanks, and feel free to ask if you have any further questions.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured