LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-03-2006, 06:37 AM   #1
manikan
LQ Newbie
 
Registered: Feb 2006
Posts: 12

Rep: Reputation: 0
errors on forward declarations.


I have a cc file which includes a header file(txTask.h) which inturn includes again a header file(DDMSDBAMgr.h)
which again includes the header file(txtask.h) from where it is called.So forward declarations are used.

But this is not accepted by g++ compiler.

could any one please throw some lights on this issue and provide a good solution?

here are the details.

txTask.h
-------------

#ifndef TXTASK_H
#define TXTASK_H


#include <DDMSDBAMgr.h>

class DDMSDBAMgrStats;

class TxMgrTask
{
public:
static int value;
static RWCString configFile;
static RWCString helpFile;
static RWCString configSection;
static RWCString digilatorFile;
static RWCString neHandler;
static RWCString nePath;

virtual void getDBAStats( DDMSDBAMgrStats &stats )
{
dbaManager->getStats( stats );
}

protected:
DDMSDBAgentManager<DDMSUsn, unsigned long> *dbaManager;

};
#endif //TXTASK_H


DDMSDBAMgr.h
---------------

#ifndef DDMSDBAMGR_H
#define DDMSDBAMGR_H

#include <txTask.h>

// forward declarations
class TxMgrTask;

class DDMSDBAMgrStats
{
public:
DDMSDBAMgrStats(){}
virtual ~DDMSDBAMgrStats(){}

long minDBAs;
long maxDBAs;
long registeredDBAs;
long noFreeAgents;
long deferredTxs;
};

template <class TxIdType, class ClientIdType> class DDMSDBAgentManager
{
public:
DDMSDBAgentManager( TxMgrTask *txmgr);
void show(static RWCString );
virtual void startMinimumDBAgents();
protected:
TxMgrTask *txTask;
}

template< class TxIdType, class ClientIdType>
DDMSDBAgentManager<TxIdType,ClientIdType>:DMSDBAgentManager( TxMgrTask *txmgr )
{
show(TxMgrTask::configFile);
txTask = txmgr;

}
virtual void DDMSDBAgentManager<TxIdType, ClientIdType>::startMinimumDBAgents()
{
if ( !TxMgrTask::value )
{
}

}

txTask.cc
--------

#include<txTask.h>



Now when i compiled txTask.cc errors were thrown as follows
n file included from ./txTask.h:10,
from txTask.C:18:
./DDMSDBAMgr.h: In constructor `DDMSDBAgentManager<TxIdType, ClientIdType>:DMSDBAgentManager(TxMgrTask*)':
./DDMSDBAMgr.h: error: incomplete type `TxMgrTask' used in nested name specifier
DDMSDBAMgr.h: In member function `virtual void DDMSDBAgentManager<TxIdType, ClientIdType>::startMinimumDBAgents()':
./DDMSDBAMgr.h: error: incomplete type `TxMgrTask' used in nested name specifier



There is a cyclic dependency between these two header files but i dont know how to resolve it.

The header files itself were not included properly while compiling cc file.

could any one please throw some lights on this issue and provide a good solution?

Regards
Mani
 
Old 02-03-2006, 07:13 AM   #2
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Rather than trying to get this to work, I would rethink it as its very bad OO design.

TxMgrTask is a prime candiate for a singleton(depending on what you are tying to do. do you realise that a static data member is the same for all the classes of this type?)
TxMgrTask data is public.
DDMSDBAMgrStats data is public.

Last edited by dmail; 02-03-2006 at 07:25 AM.
 
Old 02-03-2006, 07:26 AM   #3
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Can you please use the code tags it makes it much easier to read, thanks.

It looks as if you have code in your header file, which may be teh cause of your problems. Either remove the code to the cpp file or mark it inline.
 
Old 02-03-2006, 07:55 AM   #4
xhi
Senior Member
 
Registered: Mar 2005
Location: USA::Pennsylvania
Distribution: Slackware
Posts: 1,065

Rep: Reputation: 45
hmm.
de ja vu
 
Old 02-03-2006, 07:55 AM   #5
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Originally Posted by graemef
...

It looks as if you have code in your header file, which may be teh cause of your problems. Either remove the code to the cpp file or mark it inline.
99.999999% sure about this(why the doubt? coz graemef said this and hes normally correct lol)
class functions which are in the class declaration are inlined by default and template class functions have to be in the header.

Last edited by dmail; 02-03-2006 at 08:01 AM.
 
Old 02-03-2006, 08:06 AM   #6
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
I think I spotted a template class without a semi colon terminating the class DDMSDBAgentManager but code tags please...
 
Old 02-03-2006, 08:09 AM   #7
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
I'm only correct when I've had my morning injection of caffeine

... time for a coffee
 
Old 02-03-2006, 08:52 AM   #8
manikan
LQ Newbie
 
Registered: Feb 2006
Posts: 12

Original Poster
Rep: Reputation: 0
Plz check this snippet

first.h
-----------
#ifndef FIRST
#define FIRST
#include<iostream.h>
#include "second.h"

static int num=100;
class first
{
public:
second *ptr;
void show();
};

void first::show()
{
ptr->sum(num);
ptr->call(this,30);
}

#endif

second.h
-----------
#include<iostream.h>
#include "first.h"

class first;

class second
{
public:
void sum(int);
void call(first *fp,int);
};

void second::sum(int num)
{
cout<<num;
}

void second::call(first *fp,int)
{
cout<<fp->show();
}

main.cc:
---------

#include<iostream.h>
#include "first.h"

int main()
{
first *p=new first;
p->show();
cout<<"mani";
}



First of all i am sorry for the snippet i provided earlier.That is actually a big code i made it cut short so it would not have been good.Actually there is a error happened in one of our compilcation of our application when we were trying to port the code to linux machine.

So plz chk the above the snippet.

how can i access first.h functions in second.h file.

This is my typical case.

Regards
Mani
 
Old 02-03-2006, 08:53 AM   #9
manikan
LQ Newbie
 
Registered: Feb 2006
Posts: 12

Original Poster
Rep: Reputation: 0
errors

while compiling main.cc the errors happens is as follows

>g++ main.cc
In file included from /usr/include/c++/3.2/backward/iostream.h:31,
from main.cc:1:
/usr/include/c++/3.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <sstream> instead of the deprecated header <strstream.h>. To disable this warning use -Wno-deprecated.
In file included from first.h:4,
from main.cc:2:
second.h: In member function `void second::call(first*, int)':
second.h:20: invalid use of undefined type `struct first'
second.h:4: forward declaration of `struct first'
 
Old 02-03-2006, 09:28 AM   #10
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Okay maybe this will help:

main.cc
Code:
#include<iostream>
#include "first.h"

int main()
{
	first *p=new first;
	p->show();
	std::cout<<"mani";
}
first.cc
Code:
#include "first.h"

int first::num = 100;

void first::show()
{
	ptr->sum(num);
	ptr->call(this,30);
}
first.h
Code:
#ifndef FIRST
#define FIRST
#include<iostream>
#include "second.h"


class first
{
public:
	static int num;
	second *ptr;
	void show();
};

#endif
second.cc
Code:
#include "first.h"
#include "second.h"

void second::sum(int num)
{
	std::cout<<num<<" ";
}

void second::call(first *fp,int)
{
	if (first::num-- > 0)
		fp->show();
	
}
second.h
Code:
#ifndef SECOND
#define SECOND
#include<iostream>
//#include "first.h"

class first;

class second
{
public:
	void sum(int);
	void call(first *fp,int);
};

#endif
graeme.
 
Old 02-03-2006, 09:32 AM   #11
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
Changes that I did.

use <iostream> not <iostream.h>
use std:: to access cout

The #include of "first.h" in second.h is not necessary, but it is necessary in second.cc

I've also moved the static to inside first and changed to code so that the recursive loop will stop

graeme.
 
Old 02-03-2006, 09:49 AM   #12
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
<edit>graemef your post wasnt there when i started this one and im just saying the same thing.</edit>

Code:
first.h
-----------
#ifndef FIRST
#define FIRST
#include<iostream.h>
#include "second.h"

static int num=100;
class first
{
	public:
	second *ptr;
        void show();
};

void first::show()
{
	ptr->sum(num);
	ptr->call(this,30);
}

#endif
Code:
second.h
-----------
#include<iostream.h>
#include "first.h"

class first;

class second
{
	public:
		void sum(int);
		void call(first *fp,int);
};

void second::sum(int num)
{
	cout<<num;
}

void second::call(first *fp,int)
{
	cout<<fp->show();
}
Code:
main.cc:
---------

#include<iostream.h>
#include "first.h"

int main()
{
	first *p=new first;
         p->show();
	cout<<"mani";
}
You really need to look at what you are coding. I know this is just an example but its a bad one(twice in the same thread I've used that word?).

<iostream.h> the h is not required for c++ ansi/iso headers and for old c headers you should try <c_old_header_name>example<cstring>
cout is part of a namespace "std" you either need to say
Code:
using namespace std;
which then allows you to
Code:
 cout <<"foo" <<endl;
or you need to use the namespace and the scope operator
Code:
std::cout <<"foo" <<std::endl;
you really need to look at data hiding and proper constructors.
in main you create a pointer to a class which has a pointer to a second class which is not intilaised in the constructor. Instead i would do this at least and make ptr private.
Code:
first::first(){ptr = 0;}
If you needed a getter for the pointer adding
Code:
foo& first::get_foo( void )const {return *ptr; }
Ok lets look at what seems like a simple function call
Code:
p->show();
show does this
Code:
	ptr->sum(num);
	ptr->call(this,30);
sets sum and calls call passing the this pointer and 30;

Code:
ptr->call(this,30);
does the following
Code:
cout<<fp->show();
trys to put something which returns void in the stream?
And what does show do? it calls call which calls show which calls call which calls show which calls call.....

Last edited by dmail; 02-03-2006 at 09:55 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
g++ compilaion error in forward declarations manikan Programming 4 02-03-2006 11:39 AM
C++ function declarations and definitions... AM1SHFURN1TURE Programming 2 08-29-2005 06:57 PM
cant see .forward file in home directory >> mail forward/copy steve_babbage Linux - Newbie 0 03-02-2004 06:25 AM
Forward declarations somnium Programming 3 09-16-2003 05:00 AM
global declarations Randall Programming 50 03-15-2003 01:24 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:48 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration