-
February 5th, 2017, 03:30 PM
#1
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 .
-
February 6th, 2017, 07:51 PM
#2
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.
-
February 7th, 2017, 02:03 PM
#3
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.
-
February 7th, 2017, 04:15 PM
#4
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.
-
February 7th, 2017, 04:44 PM
#5
Re: Forward declaration is not working
But what happens with Program.h?
Last edited by Putarda; February 7th, 2017 at 04:51 PM.
-
February 7th, 2017, 04:54 PM
#6
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.
-
February 7th, 2017, 05:09 PM
#7
Re: Forward declaration is not working
I tried everything you said and it's still not working.
-
February 7th, 2017, 05:12 PM
#8
Re: Forward declaration is not working
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.
-
February 7th, 2017, 05:15 PM
#9
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"
...
-
February 7th, 2017, 05:49 PM
#10
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.
-
February 7th, 2017, 05:54 PM
#11
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.
-
February 7th, 2017, 06:55 PM
#12
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.
-
February 7th, 2017, 08:25 PM
#13
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.
-
February 8th, 2017, 12:59 AM
#14
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|