473,587 Members | 2,413 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

const 'correctness' question

I have a 'root' object that serves as a container/parent for several
other objects like so:

class myRoot {
public:
myRoot();
virtual ~myRoot();
void* operator new(size_t);
operator delete(void*);

setChildX(X*);
setChildY(Y*);
setChildZ(Z*);

private:
myRoot(const myRoot&);
myRoot operator= (const myRoot&);

X* m_x ;
Y* m_y ;
Z* m_z ;
};
with the setChild... methods, is it better to write them as ff (using
setChildX as an example):

setChildX(X*); OR
setChildX(const X*); OR even
setChildX(const X&);

with the variable declarations (using variable of type X* as an
example),

should I declare the variable to be :

X* m_x OR
const X* m_x

The intended lifecycle for the child objects is as ff:

1). They are created and initialized OUTSIDE the parent
2). Once they are assigned to the parent object, they can no longer be
changed (i.e. const)
3). The parent destroys all its children upon parent's death (i.e. in
parent's destructor)

Given the intended life cycle, what is the best way of declaring the
methods and the variables that will hold the ptrs to the child objects?

Apr 16 '06 #1
5 1780

Bit Byter wrote:
I have a 'root' object that serves as a container/parent for several
other objects like so:

class myRoot {
public:
myRoot();
virtual ~myRoot();
void* operator new(size_t);
operator delete(void*);

setChildX(X*);
setChildY(Y*);
setChildZ(Z*);

private:
myRoot(const myRoot&);
myRoot operator= (const myRoot&);

X* m_x ;
Y* m_y ;
Z* m_z ;
};
with the setChild... methods, is it better to write them as ff (using
setChildX as an example):

setChildX(X*); OR
setChildX(const X*); OR even
setChildX(const X&);

with the variable declarations (using variable of type X* as an
example),

should I declare the variable to be :

X* m_x OR
const X* m_x

The intended lifecycle for the child objects is as ff:

1). They are created and initialized OUTSIDE the parent
Bad choice unless absolutely necessary.
2). Once they are assigned to the parent object, they can no longer be
changed (i.e. const)
Can only be enforced within the parent object. Anyone else can still
change the object.
3). The parent destroys all its children upon parent's death (i.e. in
parent's destructor)
The parent should clone the children and keep its own copies.
Given the intended life cycle, what is the best way of declaring the
methods and the variables that will hold the ptrs to the child objects?


You can declare the pointer variables as const both within the object
and the parameter. You can still delete a const pointer. Again though
you cannot enforce the 'no-change' requirement except in the parent
object. Any client can change the object if they desire...especi ally
the one that created the 'child' to begin with. IE:

X * x = new X;

root.setChild(x ); // even assuming setChild has const X* as parameter
type, my X is still non-const

x.changeInterna ls(); // perfectly valid. root now has a changed X.

Apr 16 '06 #2
Bit Byter wrote:
I have a 'root' object that serves as a container/parent for several
other objects like so:

class myRoot {
public:
myRoot();
virtual ~myRoot();
void* operator new(size_t);
operator delete(void*);

setChildX(X*);
setChildY(Y*);
setChildZ(Z*);

private:
myRoot(const myRoot&);
myRoot operator= (const myRoot&);

X* m_x ;
Y* m_y ;
Z* m_z ;
};
with the setChild... methods, is it better to write them as ff (using
setChildX as an example):

setChildX(X*); OR
setChildX(const X*); OR even
setChildX(const X&);

with the variable declarations (using variable of type X* as an
example),

should I declare the variable to be :

X* m_x OR
const X* m_x

The intended lifecycle for the child objects is as ff:

1). They are created and initialized OUTSIDE the parent
What would be the life of an instance of "myRoot" without those child
objects? Wouldn't it make sense to only create a 'myRoot' once all
the child objects are ready? If so, then perhaps the constructor of
'myRoot' should take those pointers are arguments.
2). Once they are assigned to the parent object, they can no longer
be changed (i.e. const)
Again, perhaps they shouldn't be "assigned", but instead given to the
"parent object" during its construction?
3). The parent destroys all its children upon parent's death (i.e. in
parent's destructor)

Given the intended life cycle, what is the best way of declaring the
methods and the variables that will hold the ptrs to the child
objects?


The more const, the merrier. I would even consider

class myRoot {
...
myRoot(const X* px, const Y* py, const Z* pz) :
m_x(px), m_y(py), m_z(pz) { ...

const X* const m_x;
const Y* const m_y;
const Z* const m_z;
};

and do away with 'setChildXYZ' altogether.

V
--
Please remove capital As from my address when replying by mail
Apr 16 '06 #3
>
class myRoot {
...
myRoot(const X* px, const Y* py, const Z* pz) :
m_x(px), m_y(py), m_z(pz) { ...

const X* const m_x;
const Y* const m_y;
const Z* const m_z;
};

and do away with 'setChildXYZ' altogether.


The class also needs a default constructor to initaialize my_x, m_y,
m_z to NULL.
It is flexible to use setChildX, setChildY, and setChildZ for
lazy-binding repectively.

Apr 17 '06 #4
dan2online wrote:

class myRoot {
...
myRoot(const X* px, const Y* py, const Z* pz) :
m_x(px), m_y(py), m_z(pz) { ...

const X* const m_x;
const Y* const m_y;
const Z* const m_z;
};

and do away with 'setChildXYZ' altogether.


The class also needs a default constructor to initaialize my_x, m_y,
m_z to NULL.
It is flexible to use setChildX, setChildY, and setChildZ for
lazy-binding repectively.


That's a requirement for the OP to decide, but it is not necessary. As
Victor said, the more const the merrier (i.e., the easier the code is
to write, understand, and maintain), and I would certainly prefer his
version if possible.

Cheers! --M

Apr 17 '06 #5
Bit Byter wrote:
I have a 'root' object that serves as a container/parent for several
other objects like so:

class myRoot {
public:
myRoot();
virtual ~myRoot();
void* operator new(size_t);
operator delete(void*);

setChildX(X*);
setChildY(Y*);
setChildZ(Z*);

private:
myRoot(const myRoot&);
myRoot operator= (const myRoot&);

X* m_x ;
Y* m_y ;
Z* m_z ;
};
with the setChild... methods, is it better to write them as ff (using
setChildX as an example):

setChildX(X*); OR
setChildX(const X*); OR even
setChildX(const X&);

with the variable declarations (using variable of type X* as an
example),

should I declare the variable to be :

X* m_x OR
const X* m_x

The intended lifecycle for the child objects is as ff:

1). They are created and initialized OUTSIDE the parent
2). Once they are assigned to the parent object, they can no longer be
changed (i.e. const)
3). The parent destroys all its children upon parent's death (i.e. in
parent's destructor)

Given the intended life cycle, what is the best way of declaring the
methods and the variables that will hold the ptrs to the child objects?


See the other posts for answers to this question, but let me also
recommend that you use std::auto_ptr to pass objects into the owner
class in order to clearly indicate that myRoot takes over
responsibility for them. Likewise, I would recommend using a smart
pointer to hold the members for exception safety and easy of use.
std::auto_ptr would work, but std::tr1::scope d_ptr (or
boost::scoped_p tr) would be better.

Cheers! --M

Apr 17 '06 #6

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

Similar topics

5
5050
by: Bolin | last post by:
Hi all, A question about smart pointers of constant objects. The problem is to convert from Ptr<T> to Ptr<const T>. I have look up and seen some answers to this question, but I guess I am too stupid to understand and make them work. E.g. I have read that boost's smart pointers are able to do this convertion, but the following code...
3
1953
by: ded' | last post by:
Hello ! I've read in a magazine "reference parameter in operator= must be const, because in C++, temporary objects are const" and then my operator would not work with temporary objets. But, my compiler doesn't have temporary const objects. Are there any reasons to have a const reference parameter ? Thanks in advance for your help
2
2342
by: Jim Strathmeyer | last post by:
I have a weird question about const correctness when using an stl list. I have a wrapper Inventory class that holds a list of pointers to Items. (Yes, they have to be pointers.) Now, obviously the Inventory class isn't going to mutate the Items, so its Add function should be Add(const Item *), and the list should be std::list<const Item *>....
2
1345
by: Jianli Shen | last post by:
in a *.h file, there is a declaration: const ClassName *functionName() const {return oneVar;} I was confused by the two const there. can anybody help explain why we need the first const. why we need the second const here ? Thanks
10
2276
by: quantdev2004 | last post by:
Hi all, I have been deling with this kind of code: class Foo { public: void NonConstMethod() {} };
6
354
by: Alvin | last post by:
Hello, I have a static library that I created. I've been updating the source to be const-correct as according to the C++ FAQ Lite section 18 (http://www.parashift.com/c++-faq-lite/const-correctness.html). I know I should have done this in the first place, but better late than never. ;) I have been declaring inspect functions const as in:...
2
2005
by: Lorenzo Castelli | last post by:
This is an old problem of mine. Basically I have an abstract base class which represents a generic iterator over a collection of elements, and various derived classes that implement the traversing on specific data structures. For each iterator I want to be able to specify the four possible const combinations, corresponding to the various ...
34
31266
by: Perro Flaco | last post by:
Hi! I've got this: string str1; char * str2; .... str1 = "whatever"; .... str2 = (char *)str1.c_str();
16
3149
by: hzmonte | last post by:
Correct me if I am wrong, declaring formal parameters of functions as const, if they should not be/is not changed, has 2 benefits; 1. It tells the program that calls this function that the parameter will not be changed - so don't worry. 2. It tells the implementor and the maintainer of this function that the parameter should not be changed...
6
8297
by: Spoon | last post by:
Hello, I don't understand why gcc barks at me in this situation: $ cat foo.c extern void func(const int * const list, int nent); int main(void) { int *p;
0
7920
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7849
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8215
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8220
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6626
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5394
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3879
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1454
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1189
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.