Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Определение функции как ПОТОМ


Автор: Vetos 16.12.2007, 23:43
Я хотел бы узнать как сделать чтоб функция была описана дальше по коду а её можно было вызвать раньше чем она описана, извините за такое выражение мыслей.Вот типа того:
Код

void Step1(void)
{
...
Step2;
...
};
void Step2(void)
{
...
Step3;
...
};
void Step3(void)
{
...
}

Просто выдает ошибку что  [C++ Error] Main.cpp(67): E2303 Type name expected.
Может есть какоето зарезервированное слово?
Помогите Plz

Автор: archimed7592 16.12.2007, 23:46
Код

void Step1(void);
void Step2(void);
void Step3(void);

void Step1(void)
{
...
Step2();
...
};
void Step2(void)
{
...
Step3();
...
};
void Step3(void)
{
...
}

Автор: Vetos 16.12.2007, 23:49
А если это касается классов?

Автор: baldina 16.12.2007, 23:51
Код

class A;
class B;
class C;

class D {
  A* a; B* b; C* c;
};

class A {};
class B {};
class C {};


С классами чуть сложнее, опережающее объявление класса class X; покатит только когда не обязательно знать размер класса.

Автор: Vetos 16.12.2007, 23:58
А если этот класс еще и является наследником другого класса?

Автор: archimed7592 17.12.2007, 00:00
Цитата(Vetos @  16.12.2007,  23:58 Найти цитируемый пост)
А если этот класс еще и является наследником другого класса? 

Точно так же.

Автор: Vetos 17.12.2007, 00:04
Пишет что не может компилятор не создал конструктор по умолчанию ну вот короче:
[C++ Error] Main.cpp(79): E2125 Compiler could not generate default constructor for class 'Cos'
Че делать

Автор: archimed7592 17.12.2007, 00:05
Цитата(Vetos @  17.12.2007,  00:04 Найти цитируемый пост)
Че делать 

Снимать штаны и бегать.

Добавлено через 9 секунд
Код покажи.

Автор: JackYF 17.12.2007, 00:06
Цитата(Vetos @  17.12.2007,  00:04 Найти цитируемый пост)
Че делать 

код показать.

Добавлено через 32 секунды

Автор: baldina 17.12.2007, 00:07
В таком объявлении переменной A* a (равно как и в опережающем объявлении class A;) неважно, является ли он чьим то наследником. Для размещения указателя (или, например, объявления typedef) компилятору не требуется знать иерархию наследования.

Автор: Vetos 17.12.2007, 00:09
Ну хорошо только зря вы так, 
Мне не сложно но там просто кода дофига
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Main.h"
#include "math.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "CSPIN"
#pragma resource "*.dfm"
TForm1 *Form1;
int igg=0;
class TElement{
protected:
TElement *left, *right;
TElement(TElement* L,TElement* R)
{
left=L;right=R;
}
public:
~TElement(void){delete left;delete right;}
virtual double rezult(void){};
virtual TElement* copy(void){};
virtual TElement* differ(void){};
   virtual void Set_var(double X,double Y)
   {
   if (left) left->Set_var(X,Y);
   if (right)right->Set_var(X,Y);
   }
};
class Real: public TElement{
double f;
public:
  Real(double F):TElement(NULL,NULL){f=F;}
  double rezult(void)
   {
   return f;
   }
  TElement* copy(void){return new Real(f);}
  TElement* differ(void){return new Real(0);}
};
class Var: public TElement{
double x;
AnsiString n;
public:
 Var(double X=0, AnsiString N="X"):TElement(NULL,NULL){x=X;n=N;}
 double rezult(void)
 {return x;}
 TElement* copy(void)
 {return new Var(x,n);}
 TElement* differ(void)
 {return new Real(1.0);}
 void Set_var(double X, double Y){if(n=="X")x=X;else x=Y;}
};

struct Minus:public TElement{
Minus(TElement* L,TElement* R):TElement(L,R){};
double rezult(void){
return left->rezult()-right->rezult();}
TElement* copy(void){
return new Minus(left->copy(),right->copy());}
TElement* differ(void){
return new Minus(left->differ(),right->differ());}
};


class Cos:public TElement{};
class Sin:public TElement{
double x;
AnsiString n;
public:
 Sin(double X=0, AnsiString N="X"):TElement(NULL,NULL){x=X;n=N;}
 double rezult(void)
 {return sin(x);}
 TElement* copy(void)
 {return new Sin(x,n);}
 TElement* differ(void)
 {return new Minus(new Real(0),new Cos(x,n));}
 void Set_var(double X,double Y){if(n=="X")x=X;else x=Y;}
};

class Cos:public TElement{
double x;
AnsiString n;
public:
 Cos(double X=0, AnsiString N="X"):TElement(NULL,NULL){x=X;n=N;}
 double rezult(void)
 {return cos(x);}
 TElement* copy(void)
 {return new Cos(x,n);}
 TElement* differ(void)
 {return new Sin(x,n);}
 void Set_var(double X,double Y){if(n=="X")x=X;else x=Y;}
};

struct Plus:public TElement{
Plus(TElement* L,TElement* R):TElement(L,R){};
double rezult(void){
return left->rezult()+right->rezult();}
TElement* copy(void){
return new Plus(left->copy(),right->copy());}
TElement* differ(void){
return new Plus(left->differ(),right->differ());}
};

struct Mult:public TElement{
Mult(TElement* L,TElement* R):TElement(L,R){};
double rezult(void)
{return left->rezult()*right->rezult();}
TElement* copy(void)
{return new Mult(left->copy(),right->copy());}
TElement* differ(void)
{return new Plus(new Mult(left->differ(),right->copy()),new Mult(left->copy(),right->differ()));}
};

struct Div:public TElement{
Div(TElement* L,TElement* R):TElement(L,R){};
double rezult(void)
{return left->rezult()/right->rezult();}
TElement* copy(void)
{return new Div(left->copy(),right->copy());}
TElement* differ(void)
{return new Div(new Minus(new Mult(left->differ(),right->copy()),
                          new Mult(left->copy(),right->differ())),
                          new Mult(right->copy(),right->copy()));
}
};

int PosFromEnd(AnsiString s,AnsiString sub)
{
int I=s.Length();
AnsiString p;
p.SetLength(I);
for (int i=1;i<=I;i++)
  p[I-i+1]=s[i];
if (p.Pos(sub)>0)
  return I-p.Pos(sub)+1;
  else return 0;
};
TElement* form(AnsiString s){
TElement* h;
int p,I=s.Length();
AnsiString s1,s2;
if((p=PosFromEnd(s,"+"))>1)
  {
   s1=s.SubString(1,p-1);
   s2=s.SubString(p+1,I-p);
   h=new Plus(form(s1),form(s2));
  }
  else if ((p=PosFromEnd(s,"-"))>1)
     {
      s1=s.SubString(1,p-1);
      s2=s.SubString(p+1,I-p);
      h=new Minus(form(s1),form(s2));
     }
     else if((p=PosFromEnd(s,"*"))>1)
        {
         s1=s.SubString(1,p-1);
         s2=s.SubString(p+1,I-p);
         h=new Mult(form(s1),form(s2));
        }
        else if ((p=PosFromEnd(s,"/"))>1)
            {
             s1=s.SubString(1,p-1);
             s2=s.SubString(p+1,I-1);
             h=new Div(form(s1),form(s2));
            }
            else if (s=="x") h=new Var();
              else if (s=="y") h=new Var(0,"Y");
              else h=new Real(StrToFloat(s));
              return h;
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::B2Click(TObject *Sender)
{
exit(1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::B1Click(TObject *Sender)
{
TElement* x  = form(E1->Text);
TElement* y  = form(E22->Text);
TElement* f  = form(E2->Text);
TElement* f1 = f->differ();
TElement* f2 = f1->differ();
TElement* f3 = f2->differ();
double X=x->rezult();
double Y=y->rezult();
MessageBox(NULL,"j","mda",MB_OK);
f->Set_var(X,Y);
f1->Set_var(X,Y);
f2->Set_var(X,Y);
f3->Set_var(X,Y);
MessageBox(NULL,"P","mda",MB_OK);
int precision=15;
int digits=StrToFloat(CSE1->Text);
E3->Text=FloatToStrF(x->rezult(),ffFixed,precision,digits);
E4->Text=FloatToStrF(f->rezult(),ffFixed,precision,digits);
E5->Text=FloatToStrF(f1->rezult(),ffFixed,precision,digits);
E6->Text=FloatToStrF(f2->rezult(),ffFixed,precision,digits);
E7->Text=FloatToStrF(f3->rezult(),ffFixed,precision,digits);
}
//---------------------------------------------------------------------------




Вотsmile


Цитата
В таком объявлении переменной A* a (равно как и в опережающем объявлении class A;) неважно, является ли он чьим то наследником. Для размещения указателя (или, например, объявления typedef) компилятору не требуется знать иерархию наследования.



Тут просто ситуация другая я вообще кое как разобрался и написал вот эту прогу, так все работает прога считает формулы и находит производные, теперь надо добать синус и косинус, а производные их противоположны вот и возникла эта проблемка и приходится обращатся за помощью

Автор: baldina 17.12.2007, 00:12
У тебя уже есть конструктор. Поэтому (по стандарту) компилятор конструктор без параметров не генерит. И не может создать переменную без параметров имеющегося конструктора.

Автор: Vetos 17.12.2007, 00:15
Где и как это исправить?

Автор: baldina 17.12.2007, 00:16
вот тут 
Код

class Cos:public TElement{};


невозможно создать экземпляр Cos т.к. не вызывается имеющийся конструктор TElement. Точнее - компилятор не может сгенерить конструктор по умолчанию для Cos, потому что для этого надо вызвать конструктор по умолчанию TElement, которого не существует

Автор: Vetos 17.12.2007, 00:25
так мне надо конструктор туда для Cos написать или для TElement.
я просто уже запутался, помоги разобраться.
Если у TElement нет конструктора то что тогда  вот это:
Код

class TElement{
protected:
TElement *left, *right;
TElement(TElement* L,TElement* R)<<<<<<<<<<<<<<<<Это не конструктор?
{
left=L;right=R;
}

пробовал так сделать:
Код

class Cos:public TElement{
Cos(double x,AnsiString n){x=X;n=N;};};


Тогда возникает масса ошибок, и получается что надо переписать весь класс, что мне делать smile 

Автор: archimed7592 17.12.2007, 09:43
Vetos, попробем с другой стороны: ни чего надо, а чего ты хочешь? smile

Смотри, когда ты пишешь TElement myElement(L, R); , то создаётся экземпляр класса TElement с соответствующими значениями L и R. Когда же ты пишешь TElement myDefaultElement; то ты не указываешь значения L и R. Компилятор на это и ругается. Собственно вопрос: какие значения L и R ты в этом случае подразумеваешь? smile

Автор: baldina 17.12.2007, 09:51
Проблема как раз в том что у TElement есть конструктор TElement (TElement*,TElement*), поэтому компилятор не создаёт конструктор TElement() без параметров.
Тебе надо либо завести конструктор для TElement без аргументов, что-то типа
Код

TElement() : left(NULL),right(NULL) {} 

либо завести конструктор Cos (), который вызывает TElement (TElement*,TElement*).
Судя по вот этому вызову new Cos(x,n) все-таки у тебя должен быть конструктор для Cos с аргументами. Похоже ты класс Cos просто не доделал.

Автор: JackYF 17.12.2007, 09:53
Цитата(Vetos @  17.12.2007,  00:25 Найти цитируемый пост)
TElement(TElement* L,TElement* R)<<<<<<<<<<<<<<<<Это не конструктор?

ты должен явно его вызвать. В книге ты это недочитал, советую исправить.

Код

Cos(double x,AnsiString n) : TElement(что-то, ещё что-то)
{
  x=X;
  n=N;
}


Автор: Vetos 17.12.2007, 17:37
Мда, я понял, но все же что-то не то.
А я могу кусок написать в одном месте а другой кусок в другом, если нет, то получается что эта проблема нерешаема.
Просто дальше мне нужно будет вызвать Sin, и чо, опять его переписать перед Cos, и так по циклу, ну как то же должно решатся такое.
 smile 

Автор: Vetos 17.12.2007, 17:52
Ну вот, переписал кусочек Cos перед Sin. Тех ошибок уже нет, но когда компилятор натыкается на второй Cos то сразу ошибочка:
[C++ Error] Main.cpp(88): E2238 Multiple declaration for 'Cos'

Автор: archimed7592 17.12.2007, 17:57
Vetos, привожу простой пример. Если не поймёшь - иди читать книгу.
Код

class B;
class D1;
class D2;


class B
{ };

class D1
    : public B
{
    void foo();
};

class D2
    : public B
{
    void foo();
};

void D1::foo()
{
   new D2;
}

void D2::foo()
{
   new D1;
}


Автор: baldina 17.12.2007, 18:05
Цитата

Ну вот, переписал кусочек 


Vetos, это не именинный пирог. Есть правила. archimed7592 тебе правильный пример привел.
Сначала делаешь все объявления (обычно их в отдельный файл .h помещают), потом - реализацию (обычно в отдельном .cpp)
Там, где используешь эти классы, тебе нужны только объявления, т.е. надо включить .h - в том числе в файле реализации.

Автор: Vetos 17.12.2007, 18:09
А в одном проекте никак нельзя реализовать?
Просто с си я не дружу, больше с дельфями, поэтому не смогу сделать так :(

Добавлено через 11 минут и 53 секунды
Sorry, упустил из виду сообщение archimed7592'а, все работает, значит в си тоже можно приводить описание функции, а её тело писать потом. Просто за долгие годы так привык к Дельфе, что теперь трудновасто с синтаксисом в сях, все делаю по методичке, а там таких примеров нет)
БОЛЬШОЕ СПАСИБО ВСЕМ КТО ПОМОГАЛ  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)