473,378 Members | 1,475 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

templates and cyclic dependencies


Cracow, 20.09.2004

Hi,

I am posting this again, because my previous message dated
18.09. disappeared from the list (someone has cancelled it ? why ??).

I have a problem with compiling the following construction involving
cross-calls of class template methods, with additional inheritance.
I want to have three class templates:

------------------------------------------
in file "Model.h":

#include "Data.h"

template<class T> class Model
{
....
void Read(Data<T> *data);
virtual int Get_Info(void);
};

template<class T>
void Model<T>::Read(Data<T> *data)
{
....
T something = data->Get(); // Note the Data method call
}

template<class T>
int Model<T>::Get_Info(void)
{
....
}

template class Model<float>;
template class Model<double>;

---------------------------------------
in file "Model1.h":

#include "Model.h"

template<class T> class Model1 : public Model<T>
{
....
virtual int Get_Info();
};

template<class T>
int Model1<T>::Get_Info(void)
{
....
}

template class Model1<float>;
template class Model1<double>;

----------------------------------------
in File "Data.h":

#include "Model.h"

template<class T> class Data
{
Data(Model<T> *model);
....
T Get(void);
};

template<class T>
Data<T>::Data(Model<T> *model)
{
....
int info = model->Get_Info(); // Note the virtual Model method call
}

template<class T>
T Data<T>::Get(void)
{
....
}

template class Data<float>;
template class Data<double>;

------------------------------------------
In the calling unit, file "Caller.h" I want to be able to do something
like this:

#include "Model.h"
#include "Model1.h"
#include "Data.h"

template<class T> class Caller
{
....
void call(void);
};

template<class T>
Caller<T>::call(void)
{
....
Model<T> *model = new Model1<T>();
....
Data<T> *data = new Data<T>(model);
....
model->Read(data);
....
}

template class Caller<float>;
template class Caller<double>;
---------------------------------------------------

I cannot figure out where to #include the various files and/or
where to provide forward class template declarations in order to avoid
compiler errors caused by nested inclusions of the header files, as
indicated. I have tried various combinations, such as not including
the headers, but using only forward declarations, or including the
headers after class declarations but before the method bodies. Nothing
helps.

I would appreciate any advice, also how to possibly redesign
the above code in order to have the same functionality and logic.
(I hope I have not introduced any spurious errors into the above
description, I am just writing this from memory, not from the
real code. In the real code certainly there are no typos or similar
errors. Please pay attention to the problem structure, not to details
of the statements). I use BCB 4.0, if this has any meaning.

Sincerely,

L.B.

*-------------------------------------------------------------------*
| Dr. Leslaw Bieniasz, |
| Institute of Physical Chemistry of the Polish Academy of Sciences,|
| Department of Electrochemical Oxidation of Gaseous Fuels, |
| ul. Zagrody 13, 30-318 Cracow, Poland. |
| tel./fax: +48 (12) 266-03-41 |
| E-mail: nb******@cyf-kr.edu.pl |
*-------------------------------------------------------------------*
| Interested in Computational Electrochemistry? |
| Visit my web site: http://www.cyf-kr.edu.pl/~nbbienia |
*-------------------------------------------------------------------*
Jul 22 '05 #1
3 1910
Leslaw Bieniasz wrote:
I am posting this again, because my previous message dated
18.09. disappeared from the list (someone has cancelled it ? why ??).
Nobody but you can cancel your message (usually). Check with your
ISP.
I have a problem with compiling the following construction involving
cross-calls of class template methods, with additional inheritance.
I want to have three class templates:

------------------------------------------
in file "Model.h":

#include "Data.h"

template<class T> class Model
{
...
void Read(Data<T> *data);
The compiler doesn't usually need to know what 'Data<T>' is here.
Since you're declaring the function with the pointer, you may just
forward-declare 'Data' at the beginning of 'Model.h'.
virtual int Get_Info(void);
};

template<class T>
void Model<T>::Read(Data<T> *data)
{
...
T something = data->Get(); // Note the Data method call
Here you'd usually need to know what 'Data' is since you're using
a member of it. The compiler needs to know the layout of the class
template.
}

template<class T>
int Model<T>::Get_Info(void)
{
...
}

template class Model<float>;
template class Model<double>;
If you have explicit instantiations, you may hide all the implementation
in a C++ file. It's going to be even simpler from the inclusion point
of view.

---------------------------------------
in file "Model1.h":

#include "Model.h"

template<class T> class Model1 : public Model<T>
{
...
virtual int Get_Info();
};

template<class T>
int Model1<T>::Get_Info(void)
{
...
}

template class Model1<float>;
template class Model1<double>;

----------------------------------------
in File "Data.h":

#include "Model.h"

template<class T> class Data
{
Data(Model<T> *model);
Same here. Since you declared a use of a pointer to Model<T>, you
just need to let the compiler know that Model<T> is a class template.
[Forward-]Declare the template at the beginning of the file instead
of including 'Model.h'.
...
T Get(void);
};

template<class T>
Data<T>::Data(Model<T> *model)
{
...
int info = model->Get_Info(); // Note the virtual Model method call
}

template<class T>
T Data<T>::Get(void)
{
...
}

template class Data<float>;
template class Data<double>;

------------------------------------------
In the calling unit, file "Caller.h" I want to be able to do something
like this:

#include "Model.h"
#include "Model1.h"
#include "Data.h"

template<class T> class Caller
{
...
void call(void);
};

template<class T>
Caller<T>::call(void)
{
...
Model<T> *model = new Model1<T>();
...
Data<T> *data = new Data<T>(model);
...
model->Read(data);
...
}

template class Caller<float>;
template class Caller<double>;
---------------------------------------------------

I cannot figure out where to #include the various files and/or
where to provide forward class template declarations in order to avoid
compiler errors caused by nested inclusions of the header files, as
indicated. I have tried various combinations, such as not including
the headers, but using only forward declarations, or including the
headers after class declarations but before the method bodies. Nothing
helps.
This is what should help: begin by forward-declaring everything and
then add the inclusions only when it is absolutely necessary. My
suspicion is that if you split your code into declarations and member
definitions, and then leave the declarations in the headers and move
the definitions in source files, you shouldn't have to include any
headers into headers, only into source files.

The compiler should know what to do because you provide the explicit
instantiations of your templates.
[...]


V
Jul 22 '05 #2

Cracow, 22.09.2004

Hello,

On Mon, 20 Sep 2004, Victor Bazarov wrote:
I have a problem with compiling the following construction involving
cross-calls of class template methods, with additional inheritance.
I want to have three class templates:

------------------------------------------
in file "Model.h":

#include "Data.h"

template<class T> class Model
{
...
void Read(Data<T> *data);
The compiler doesn't usually need to know what 'Data<T>' is here.
Since you're declaring the function with the pointer, you may just
forward-declare 'Data' at the beginning of 'Model.h'.
virtual int Get_Info(void);
};

template<class T>
void Model<T>::Read(Data<T> *data)
{
...
T something = data->Get(); // Note the Data method call


Here you'd usually need to know what 'Data' is since you're using
a member of it. The compiler needs to know the layout of the class
template.
}

template<class T>
int Model<T>::Get_Info(void)
{
...
}

template class Model<float>;
template class Model<double>;


If you have explicit instantiations, you may hide all the implementation
in a C++ file. It's going to be even simpler from the inclusion point
of view.

---------------------------------------
in file "Model1.h":

#include "Model.h"

template<class T> class Model1 : public Model<T>
{
...
virtual int Get_Info();
};

template<class T>
int Model1<T>::Get_Info(void)
{
...
}

template class Model1<float>;
template class Model1<double>;

----------------------------------------
in File "Data.h":

#include "Model.h"

template<class T> class Data
{
Data(Model<T> *model);


Same here. Since you declared a use of a pointer to Model<T>, you
just need to let the compiler know that Model<T> is a class template.
[Forward-]Declare the template at the beginning of the file instead
of including 'Model.h'.
...
T Get(void);
};

template<class T>
Data<T>::Data(Model<T> *model)
{
...
int info = model->Get_Info(); // Note the virtual Model method call
}

template<class T>
T Data<T>::Get(void)
{
...
}

template class Data<float>;
template class Data<double>;

------------------------------------------
In the calling unit, file "Caller.h" I want to be able to do something
like this:

#include "Model.h"
#include "Model1.h"
#include "Data.h"

template<class T> class Caller
{
...
void call(void);
};

template<class T>
Caller<T>::call(void)
{
...
Model<T> *model = new Model1<T>();
...
Data<T> *data = new Data<T>(model);
...
model->Read(data);
...
}

template class Caller<float>;
template class Caller<double>;
---------------------------------------------------

I cannot figure out where to #include the various files and/or
where to provide forward class template declarations in order to avoid
compiler errors caused by nested inclusions of the header files, as
indicated. I have tried various combinations, such as not including
the headers, but using only forward declarations, or including the
headers after class declarations but before the method bodies. Nothing
helps.

This is what should help: begin by forward-declaring everything and
then add the inclusions only when it is absolutely necessary. My
suspicion is that if you split your code into declarations and member
definitions, and then leave the declarations in the headers and move
the definitions in source files, you shouldn't have to include any
headers into headers, only into source files.

The compiler should know what to do because you provide the explicit
instantiations of your templates.


This will not work, because according to the current C++ standard all
template stuff (except perhaps for the explicit instantiations) MUST go
into headers, otherwise the code cannot be compiled. This is the
problem. The errors are detected while parsing the definitions of the
class template methods, not while parsing the class template declaration (in the
latter case forward declarations are indeed sufficient), because in the
definitions not only pointers or references to other classes occur,
but method calls.

L.B.
*-------------------------------------------------------------------*
| Dr. Leslaw Bieniasz, |
| Institute of Physical Chemistry of the Polish Academy of Sciences,|
| Department of Electrochemical Oxidation of Gaseous Fuels, |
| ul. Zagrody 13, 30-318 Cracow, Poland. |
| tel./fax: +48 (12) 266-03-41 |
| E-mail: nb******@cyf-kr.edu.pl |
*-------------------------------------------------------------------*
| Interested in Computational Electrochemistry? |
| Visit my web site: http://www.cyf-kr.edu.pl/~nbbienia |
*-------------------------------------------------------------------*
Jul 22 '05 #3
Leslaw Bieniasz wrote:
[...]
This will not work, because according to the current C++ standard all
template stuff (except perhaps for the explicit instantiations) MUST go
into headers, otherwise the code cannot be compiled.
I don't want this to go into "must -- must not" type of argument, but
I don't have time to provide you with examples either. I will just say
that if you define the template class (with all members _declared_) and
use _explicit_instantiations_ in the same header, you _don't_ need all
the member definitions in the same header. If you know what I am talking
about, you can try it yourself. Sapienti sat.

Otherwise, use a compiler that supports 'export' keyword. IOW, what you
said about "according to the current C++ standard" only shows your poor
knowledge of the standard. No offense intended.
[...]


V
Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Brian Sabolik | last post by:
I'm not sure if I've broken any Object Oriented rules or not, but ... I have projects in 2 different solutions that need to use each other's methods. Therefore I may have an "update" method in...
9
by: John Doe | last post by:
Hi all, Regarding those cyclic dependencies of classes (like cases in which class A refers to class B and class B to class A): can they ALL be resolved by forward defining classes, and by...
3
by: Dennis Lerche | last post by:
Hi I have a problem regarding cyclic dependency, yeahh I know bad design. But right at this moment I can't see how it should be redesigned to avoid this. The problem is that I just can't get it...
8
by: Christian Christmann | last post by:
Hi, I've a problem with including header files. class A requires header file of class B class B requires header file of class C class C requires header file of class A As can be seen the...
4
by: Alex Sedow | last post by:
For example, System.dll contains assembly reference to System.XML.dll, System.XML.dll refers to System.dll. Some another open projects contain cyclic assembly dependencies too. How C# compiler...
3
by: fc2004 | last post by:
Hi, Is there any tools that could report where cyclic header dependency happens? this would be useful when working with a large project where tens or hundreds of headers files may form complex...
12
by: Ben | last post by:
I'm kind of new to creating templates. I've made some small class and function templates in the past and I have used quite of bit of the STL, but I am having problems tyring to create templates. ...
1
by: xiaohuamao | last post by:
Beside declare independent abstract classes, is there any other methods to solve the problem of cyclic dependencies?Like the following one, which causes compile error of undefined type. class...
10
by: toton | last post by:
Hi I have a class called Session, which stores a vector of Page, like vector<PageAlso each Page need's to know the Session to which it is attached. Thus I have, (the classes has many other...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.