"missing storage-class or type specifiers error" while declaring child form

kkirtac

Newcomer
Joined
Apr 25, 2006
Messages
13
i have declared a child form in the parent form 'Form1' .
' public: static Form2* childform; '
but in the line of ' public: static Form2* childform; ' where i ve defined the pointer, i receive the error 'missing storage-class or type specifiers' . i ve already included Form2.h in Form1.h and i create an instance of Form2 in Form1's constructor with 'new' operator... so why i receive this error...?
regards.
 
Which version of C++ are you using? If it is version 8 (C++/CLI) then you need to use "handles" with .Net objects. Instead of using the * character for .Net references, you should use the ^ character. Microsoft made this change to represent the difference between a real pointer and a .Net object reference.
 
marble_eater said:
Which version of C++ are you using? If it is version 8 (C++/CLI) then you need to use "handles" with .Net objects. Instead of using the * character for .Net references, you should use the ^ character. Microsoft made this change to represent the difference between a real pointer and a .Net object reference.

i m using visual studio .net 2003
 
My guess is that you are forgetting to include something in your header files that isn't allowing the compiler to fully understand the definition of Form2.

I'm a little rusty on my C++, so humor me with this one. Why are you declaring the childForm pointer as static? You won't actually be assigning memory to that pointer until you create a new Form1 Object so why bother making it static if you can't use it without first instantiating a Form1 Object?


By the way, * is an operator, the dereference operator. Characters are those things that go between single quotes:
Code:
char superChar = 'a';
That is pretty cool about the ^ operator for managed (I assume?) objects. C++.Net looks less like its GNU cousin every day.
 
mskeel said:
My guess is that you are forgetting to include something in your header files that isn't allowing the compiler to fully understand the definition of Form2.

I'm a little rusty on my C++, so humor me with this one. Why are you declaring the childForm pointer as static? You won't actually be assigning memory to that pointer until you create a new Form1 Object so why bother making it static if you can't use it without first instantiating a Form1 Object?


By the way, * is an operator, the dereference operator. Characters are those things that go between single quotes:
Code:
char superChar = 'a';
That is pretty cool about the ^ operator for managed (I assume?) objects. C++.Net looks less like its GNU cousin every day.

well, include files are ok and maybe you are right about the static thing..but the error still exists and it does not work using ^ operator...i m on .net2003 thanks anyways
 
Yes, * is an operator. It is also an ASCII/Unicode character. The term character has a definition beyond that of programming data types. A text file/code file is actually a sequence of characters written to the hard disk, no? All text, even beyond the realm of all that is digital, is ultimately composed of characters.


Besides, why the need to split hairs? Even if I had said something that didn't entirely make sense, you got my meaning, no?
 
marble_eater said:
Yes, * is an operator. It is also an ASCII/Unicode character. The term character has a definition beyond that of programming data types. A text file/code file is actually a sequence of characters written to the hard disk, no? All text, even beyond the realm of all that is digital, is ultimately composed of characters.


Besides, why the need to split hairs? Even if I had said something that didn't entirely make sense, you got my meaning, no?

cant't get the point..what you mean actually? yes its a ascii operator but dont we use it as a reference operator in c++ ? yes ofcourse..
 
What?

I'm not sure whether or not you understood, but the point I was making to mskeel was that the * operator is a character.

Also, I opened up C++ 2005 and tried public: static Form2^ childform; (which is the equivalent to public: static Form2* childform; in C++ 2003) and got no errors. I would have to say that the error is being caused by some code that you didn't post. I know you said that the includes were right, but that looks to be the most likely problem.
 
here are the basic code:
//Parent form's header file -> Form1.h
Code:
#include "costForm.h" //this is the child form's header
namespace Segmentation
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System:: Data;
using namespace System:: Drawing;
using namespace System::IO;

public __gc class Form1 : public System::Windows::Forms::Form
{

public:

Form1(void)
{
InitializeComponent();
}

protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super:: Dispose(disposing);
}
private:
System::ComponentModel::Container * components;

public: static Bitmap* source;
public: static double* img;
public: static Node* nodes;

public: costForm *cform; //declaring the pointer for child
//...
//...
//...
//...
//...

private: System::Void dynamicCostMenuItem_Click(System::Object * sender, System::EventArgs * e)
{
costselected = true;
cform = new costForm(this); //creating an object of thechild with a reference of the 
                                      //parent form
cform->MdiParent = this;
this->ClientSize = System:: Drawing::Size(source->Width+ cform->Width, source->Height);
(cform->Location).X = (this->pictureBox1->Location).X + cform->Width ;
(cform->Location).Y = (this->Location).Y ;

cform->Show();

}

here i have no problem declaring a pointer of the child and reaching the public members of it from the parent form..

and here is the child's header file in detail
#include "Form1.h" // i include the parent's header in child form

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 Segmentation
{

public __gc class costForm : public System::Windows::Forms::Form
{
public:
costForm( Form* f)
{
InitializeComponent();
parent = f; //equalize the 'parent' member of the child form
              //to the reference taken before
}

protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super:: Dispose(disposing);
}

private: Form1 *parent; // declaring the pointer of the parent
//errors : error C2143: syntax error : missing ';' before '*'
//'Segmentation::costForm::Form1' : missing storage-class or type specifiers
these errors are in the line of "private: Form1 *parent;"
 
Last edited by a moderator:
I'll be honest. Include files hurt my head, especially with circular dependacies (costForm has a Form1 member and Form1 has a costForm member). It seems to me, though, that costForm is being declared before Form1 (by means of an include), so the compiler can't find Form1.

I opened C++ 2005, and although it is different, I did manage to reproduced your problem. I made two forms, each of which had a pointer to the other type of form. I tried different includes and found that no matter what both forms would fail to compile; the first would fail because the second isn't declared, then the second would fail because the first failed.

Unfortunately, I didn't what one should do in such a situation, so I looked at this Wikipedia article that I found using a google search.

The key would be a forward declaration. Something similar to this:
Code:
__gc class Form1;
should be added directly above your costForm declaration to let the compiler know that a Form1 class will be declared so that the compiler will allow you to reference that type.

Hope that helps.
 
yes i already tried that before but it didnt help :( but where exactly you want me to place that line of code "__gc class Form1;" well, i tried it in many places inside the costForm.h code but it didnt help..yes i also know that there is a circular dependency, costForm has a Form1 member and Form1 has a costForm member..but how can i reach the members of the parent in a different way..a complicated situation..thanks for all..
 
If you place __gc class Form1; immediately before public __gc class costForm : public System::Windows::Forms::Form{ and __gc class costForm; immediately before public __gc class Form1 : public System::Windows::Forms::Form { all should go well. Again, I'm no expert, but this worked for me.

Code:
#include "costForm.h" //this is the child form's header
namespace Segmentation
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System:: Data;
using namespace System:: Drawing;
using namespace System::IO;

[COLOR=Red]__gc class costForm;[/COLOR]
public __gc class Form1 : public System::Windows::Forms::Form
{

public:

Form1(void)
{
InitializeComponent();
}

protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super:: Dispose(disposing);
}
private:
System::ComponentModel::Container * components;

public: static Bitmap* source;
public: static double* img;
public: static Node* nodes;

public: costForm *cform; //declaring the pointer for child
//...
//...
//...
//...
//...

private: System::Void dynamicCostMenuItem_Click(System::Object * sender, System::EventArgs * e)
{
costselected = true;
cform = new costForm(this); //creating an object of thechild with a reference of the 
                                      //parent form
cform->MdiParent = this;
this->ClientSize = System:: Drawing::Size(source->Width+ cform->Width, source->Height);
(cform->Location).X = (this->pictureBox1->Location).X + cform->Width ;
(cform->Location).Y = (this->Location).Y ;

cform->Show();

}

here i have no problem declaring a pointer of the child and reaching the public members of it from the parent form..

and here is the child's header file in detail
#include "Form1.h" // i include the parent's header in child form

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 Segmentation
{
[COLOR=Red]__gc class Form1;[/COLOR]
public __gc class costForm : public System::Windows::Forms::Form
{
public:
costForm( Form* f)
{
InitializeComponent();
parent = f; //equalize the 'parent' member of the child form
              //to the reference taken before
}

protected:
void Dispose(Boolean disposing)
{
if (disposing && components)
{
components->Dispose();
}
__super:: Dispose(disposing);
}

private: Form1 *parent; // declaring the pointer of the parent
 
I'm no expert programmer and I'm definately not a c++ expert (closest I've been to it is looking at it a few times at uni). But your comment of "but how can i reach the members of the parent in a different way" intruiged me. If all you need to do is access members from the opposite form, then (in c# at least) you could simply pass a reference into the constructor of the other form. This shouldn't cause a circular dependency problem as one of the objects will definately be created before the other, passing a reference to itself to the other form.
 
cags said:
If all you need to do is access members from the opposite form, then (in c# at least) you could simply pass a reference into the constructor of the other form.
That is essentially (I think) what he is doing. The trick in C++, though is that the complier needs to know what it is dealing with before it can do anything with it. In C# I think a lot of this stuff is handled behind the scenes for us (through reflection/CLR/Object hierarchy maybe?). In C++ you have to explicitly tell the compiler stuff, usually in your header files. So, if a definition for a class is not #included, then the compiler is going to barf if you try to use that class to any capacity. Sometimes, you have classes that talk back and forth (like maybe an owner that instantiates and an ownee that points to its owner) and both will need to know about the other. With certain, strict compilers, you can't even define a function before you tell the compiler it's coming.

To get around double declarations where X needs to know about Y and Y needs to know about X and they both #include each other in their header files you would do something like this:
Code:
#ifndef nameOFHeader_h
#define nameOfHeader_h
// ... function headers and class definitions
#endif

But this is a loosely related side tangent, so I'll end it there. It seems like marble_eater pretty much nailed it.
 
I'm just going elaborate a little.

The way a C++ compiler works is pretty different from the way a C# compiler works. C++ compilers go through the code in one sweep. All of the #includes basically pull all the different code files into one single, long code file at compile time. The compiler goes through once, from beginning to end, so at any given point in the code, the only objects that are known to the compiler are objects that are declared earlier in code. When A depends on B which depends on A the paradox is that you can't declare A before B and declare B before A.

C# makes life a little easier. It picks out all the code elements before it starts compiling the statements, so you really don't need to worry about which code elements depend on other code elements.
 
Back
Top