473,383 Members | 1,821 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,383 software developers and data experts.

cyclic defination problem.

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 things, I copied only the
portion i needed)
in Session.hpp

#include "Page.hpp"
class Session {
private:
std::vector<Page_pages;
};

while in Page.hpp
class Session;// forward decl
class Page{
private:
Session* _session;
public:
Page(Session* session) : _session(session) {}
};
Is it the best way to remove cyclic definition problem? Or any way I
can store a reference to Session rather than pointer to Session?

Thanks
abir

Aug 14 '06 #1
10 1733
toton wrote:
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 things, I copied only the
portion i needed)
in Session.hpp

#include "Page.hpp"
class Session {
private:
std::vector<Page_pages;
};

while in Page.hpp
class Session;// forward decl
class Page{
private:
Session* _session;
public:
Page(Session* session) : _session(session) {}
};
Is it the best way to remove cyclic definition problem? Or any way I
can store a reference to Session rather than pointer to Session?
Whether to store a reference to Session or a pointer to Session is up
to you, and either would require using some kind of forward declaration,
which you have done already. Keep in mind that if you store a reference
in 'Page' you will have to initialise it during construction of the Page
object and you will not be able to change it during the Page's lifetime.
If that fits your design, prefer the reference. Otherwise, go with the
pointer.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 14 '06 #2
toton wrote:
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 things, I copied only the
portion i needed)
in Session.hpp

#include "Page.hpp"
class Session {
private:
std::vector<Page_pages;
};

while in Page.hpp
class Session;// forward decl
class Page{
private:
Session* _session;
public:
Page(Session* session) : _session(session) {}
};
Is it the best way to remove cyclic definition problem? Or any way I
can store a reference to Session rather than pointer to Session?
You could have a reference (it's simple enough to test -- did you try
it?). See this article for more on forward declarations and breaking
dependencies:

http://www.gotw.ca/publications/mill04.htm

Cheers! --M

Aug 14 '06 #3
"mlimber" <ml*****@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com
toton wrote:
>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 things, I copied only the
portion i needed)
in Session.hpp

#include "Page.hpp"
class Session {
private:
std::vector<Page_pages;
};

while in Page.hpp
class Session;// forward decl
class Page{
private:
Session* _session;
public:
Page(Session* session) : _session(session) {}
};
Is it the best way to remove cyclic definition problem? Or any way I
can store a reference to Session rather than pointer to Session?

You could have a reference (it's simple enough to test -- did you try
it?).
Use of a reference is a little tricky.

Page is stored in a vector and objects stored in standard containers must be
assignable. The compiler won't generate an assignment operator for Page,
because a reference cannot be re-seated.

You could write an assignment operator for Page to get the code to compile,
but any user-defined assignment operator likewise will not re-seat a
reference, so there could be some unexpected behaviour.

--
John Carson
Aug 14 '06 #4
John Carson wrote:
"mlimber" <ml*****@gmail.comwrote in message
news:11**********************@h48g2000cwc.googlegr oups.com
toton wrote:
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 things, I copied only the
portion i needed)
in Session.hpp

#include "Page.hpp"
class Session {
private:
std::vector<Page_pages;
};

while in Page.hpp
class Session;// forward decl
class Page{
private:
Session* _session;
public:
Page(Session* session) : _session(session) {}
};
Is it the best way to remove cyclic definition problem? Or any way I
can store a reference to Session rather than pointer to Session?
You could have a reference (it's simple enough to test -- did you try
it?).

Use of a reference is a little tricky.

Page is stored in a vector and objects stored in standard containers must be
assignable. The compiler won't generate an assignment operator for Page,
because a reference cannot be re-seated.

You could write an assignment operator for Page to get the code to compile,
but any user-defined assignment operator likewise will not re-seat a
reference, so there could be some unexpected behaviour.
Right, and the same is true if one used a const pointer to a Session
object instead (const-correctness and all that). I took the OP's
question to be about whether a forward declaration would work with a
reference as well as a pointer, which, of course, it will.

Cheers! --M

Aug 14 '06 #5

Victor Bazarov wrote:
toton wrote:
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 things, I copied only the
portion i needed)
in Session.hpp

#include "Page.hpp"
class Session {
private:
std::vector<Page_pages;
};

while in Page.hpp
class Session;// forward decl
class Page{
private:
Session* _session;
public:
Page(Session* session) : _session(session) {}
};
Is it the best way to remove cyclic definition problem? Or any way I
can store a reference to Session rather than pointer to Session?

Whether to store a reference to Session or a pointer to Session is up
to you, and either would require using some kind of forward declaration,
which you have done already. Keep in mind that if you store a reference
in 'Page' you will have to initialise it during construction of the Page
object and you will not be able to change it during the Page's lifetime.
If that fits your design, prefer the reference. Otherwise, go with the
pointer.
I prefer to store reference. Infact I want to do it in ctor, as you
have mentioned. I prefer not to change it. I also prefer to have a
constant reference.
like
class Page{
private:
const Session& _session;
};
but, at the same time, I prefer to pass it in the constructor as
reference, rather than pointer.
like Page(const Session& session) : _session(session) {}
Here some cyclic definition creating problem. I am not sure whether
this can be done, i.e only forward defination will allow me to do so or
not, or in my case problem is coming from some other cyclic
definition.
Thanks...
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 14 '06 #6
toton wrote:
[..]
I prefer to store reference. Infact I want to do it in ctor, as you
have mentioned. I prefer not to change it. I also prefer to have a
constant reference.
like
class Page{
private:
const Session& _session;
};
but, at the same time, I prefer to pass it in the constructor as
reference, rather than pointer.
like Page(const Session& session) : _session(session) {}
Here some cyclic definition creating problem. I am not sure whether
this can be done, i.e only forward defination will allow me to do so
or not, or in my case problem is coming from some other cyclic
definition.
Pull the _implementation_ of the constructor out of your 'Page' class
definition. Place it along with other Page's member functions in its
own implementation file (translation unit), and include both headers
in it (in any order) before defining all functions.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 14 '06 #7
Victor Bazarov wrote:
toton wrote:
[..]
I prefer to store reference. Infact I want to do it in ctor, as you
have mentioned. I prefer not to change it. I also prefer to have a
constant reference.
like
class Page{
private:
const Session& _session;
};
but, at the same time, I prefer to pass it in the constructor as
reference, rather than pointer.
like Page(const Session& session) : _session(session) {}
Here some cyclic definition creating problem. I am not sure whether
this can be done, i.e only forward defination will allow me to do so
or not, or in my case problem is coming from some other cyclic
definition.

Pull the _implementation_ of the constructor out of your 'Page' class
definition. Place it along with other Page's member functions in its
own implementation file (translation unit), and include both headers
in it (in any order) before defining all functions.
Now cyclic definition problem is solved, but one more problem arises.
When I declare Session as pointer inside Page, and use a vector<Page>
inside session, it works fine.

However, when I declare Session as reference inside Page and use
vector<Pagein session, vector<Pageunable to find the assignment
operator for Page.
I hadn't defined the assignment operator for Page explicitly, ( I only
have a ctor, & virtual dtor, not defined copy ctor, assignment operator
or equality operator explicitly). It seems, that for the reference
case, Page class is not defining assignment operator automatically,
however it defines when I am passing pointer to Session in Page. and
thus vector<Pageis having problem inside Session class.
Do I need to define assignment operator explicitly in this case?
thanks
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 16 '06 #8
toton wrote:
[..]
Now cyclic definition problem is solved, but one more problem arises.
When I declare Session as pointer inside Page, and use a vector<Page>
inside session, it works fine.

However, when I declare Session as reference inside Page and use
vector<Pagein session, vector<Pageunable to find the assignment
operator for Page.
I hadn't defined the assignment operator for Page explicitly, ( I only
have a ctor, & virtual dtor, not defined copy ctor, assignment
operator or equality operator explicitly). It seems, that for the
reference case, Page class is not defining assignment operator
automatically, however it defines when I am passing pointer to
Session in Page. and thus vector<Pageis having problem inside
Session class.
Do I need to define assignment operator explicitly in this case?
thanks
Yes, assignment operators are very tricky when your class has a member
that is a reference. References cannot be "reseated", i.e. made to
refer to another object than the one with which they were initialised.
So, imagine you have

class A {};
class B {
A & a;
public:
B(A& ra) : a(ra) {}
};

The compiler does not know how to generate the assignment operator
for class 'B', since the assignment semantics for references are to
assign the objects and since you're keeping the reference in 'B', you
clearly don't want to affect the objects you refer to. You can write
your own assignment operator and forgo doing anything special about
the reference member (like this:

B& operator =(const B& other_b) {
// do nothing
return *this;
}

) which means that when assigned new value, a B object will retain
the reference, IOW its 'a' member will still refer to what the object
was constructed to refer to. Is that what you want? I don't know.
If you want "reseat-ability", use pointers.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 16 '06 #9

Victor Bazarov wrote:
toton wrote:
[..]
Now cyclic definition problem is solved, but one more problem arises.
When I declare Session as pointer inside Page, and use a vector<Page>
inside session, it works fine.

However, when I declare Session as reference inside Page and use
vector<Pagein session, vector<Pageunable to find the assignment
operator for Page.
I hadn't defined the assignment operator for Page explicitly, ( I only
have a ctor, & virtual dtor, not defined copy ctor, assignment
operator or equality operator explicitly). It seems, that for the
reference case, Page class is not defining assignment operator
automatically, however it defines when I am passing pointer to
Session in Page. and thus vector<Pageis having problem inside
Session class.
Do I need to define assignment operator explicitly in this case?
thanks

Yes, assignment operators are very tricky when your class has a member
that is a reference. References cannot be "reseated", i.e. made to
refer to another object than the one with which they were initialised.
So, imagine you have

class A {};
class B {
A & a;
public:
B(A& ra) : a(ra) {}
};

The compiler does not know how to generate the assignment operator
for class 'B', since the assignment semantics for references are to
assign the objects and since you're keeping the reference in 'B', you
clearly don't want to affect the objects you refer to. You can write
your own assignment operator and forgo doing anything special about
the reference member (like this:

B& operator =(const B& other_b) {
// do nothing
return *this;
}

) which means that when assigned new value, a B object will retain
the reference, IOW its 'a' member will still refer to what the object
was constructed to refer to. Is that what you want? I don't know.
If you want "reseat-ability", use pointers.
In my situation, the reference of Session (or pointer, still not
decided! ) to a Page, and Page can not change the Session, it can only
refer to the Session it belongs. Thus Page knows the Session it belongs
at construction (in ctor) , and do not have a method like setSession.
So, I don't think it is "reseat-able", a Page is associated with a
Session throughout it's lifetime, and Session can remove a Page from
its evctor<Pageif the processing is done. Similarly, a Char knows The
Page it belongs, and can refer it, but itself can't change the Page it
belongs. However a Page can remove the a Char from it's deque<Char>.
That is why I thught reference is a better option.
If I define the assignment operator as you have mentioned, does it mean
that for two page
Page p1,p2; if I write p1 = p2, then p1 will not get modified
irrespective of what p2 is or will it be same object as p2 ?
Also, will the copy constructor work in its usual way? As I have a
vector<Pageinside the session, copy contsructor for Page is needed
for Session to work properly.
thanks.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 16 '06 #10
toton wrote:
[..]
If I define the assignment operator as you have mentioned, does it
mean that for two page
Page p1,p2; if I write p1 = p2, then p1 will not get modified
irrespective of what p2 is or will it be same object as p2 ?
Modify anything you want, just don't touch the reference (in any way).
The assignment operator should perform all actions necessary to copy
data members. It's not possible to copy references (only copy objects
to which they refer), so usually you'd leave references alone. Thus,
the reference refers to the same object throughout its lifetime, no
matter whether the other members get changed along the way using the
assignment operator.
Also, will the copy constructor work in its usual way?
That should be fine.
As I have a
vector<Pageinside the session, copy contsructor for Page is needed
for Session to work properly.
Sure. Will not be a problem.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 16 '06 #11

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

Similar topics

3
by: Thomas Mailund | last post by:
Hi group. I have a problem with some C extensions I am working with and hope that some of you can help. Basically, I am wrapping a a tree structure from C where I have python methods for...
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...
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: scl | last post by:
two class with same name exist in different dynamic linked library: a.so class REGION() { public: .... ~REGION() {} } b.so
5
by: free2cric | last post by:
Hi, how to detect head and tail in cyclic doubly link list ? Thanks, Cric
2
by: Matthias Kramm | last post by:
Hi All, I'm having a little bit of trouble using the "imp" module to dynamically import modules. It seems that somehow cyclic references of modules don't work. I'm unable to get the following...
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...
1
by: Joe Peterson | last post by:
I've been doing a lot of searching on the topic of one of Python's more disturbing issues (at least to me): the fact that if a __del__ finalizer is defined and a cyclic (circular) reference is...
1
by: pallav | last post by:
I have to header files, circuit.h and latch.h that reference each other and are causing a cyclic dependency. latch.h file #include "circuit.h" typedef boost::shared_ptr<struct LatchLatchPtr;...
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
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
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: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

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.