473,404 Members | 2,137 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,404 software developers and data experts.

A little confused with this (const ptrs)

I have the following methods:

static void Foo::setBar(const Bar*) ; //store a copy of Bar
static const Bar* Foo::getBar(void) const ; //return an UNMODIFIABLE ptr
to our internal copy

In another part of my code , I retrieved and used Bar as follows:

....
const Bar* temp = NULL ;
....
//retrieve and use
temp = Foo::getBar();
.....
delete temp ; // <- compiler did not complain (what's happend ? - has
Foo::Bar really been deleted?)

Basicaly, this is what I want to do:

1). store a copy of Bar 'safely' in Foo
2). Be able to request a ptr to Bar and use it without being able to
modify it
3). I want Foo::setBar() to be able to replace (i.e. destroy first, then
replace) the original Foo::Bar* variable

Questions:

1). How do I do that?

I was doing this:

class Foo
{
public:
Foo(){ m_bar = NULL ;}

/* I need these static so I can use Bar* in some 'stand alone' C
callback functions*/
static void setBar(const Bar* b) {
if (m_bar) delete m_bar ;
m_bar = CopyOf(b) ;
}

static const B* getBar(void)const { return m_bar ; }
private:
Bar* m_bar ;
}

whats wrong with the above?

May 14 '06 #1
5 1620
Bit byte wrote:
I have the following methods:

static void Foo::setBar(const Bar*) ; //store a copy of Bar
Why a pointer, not a reference?
static const Bar* Foo::getBar(void) const ; //return an UNMODIFIABLE ptr
to our internal copy
You mean "a pointer to an UNMODIFIABLE Bar". Again, why a pointer, not a
reference?
In another part of my code , I retrieved and used Bar as follows:

...
const Bar* temp = NULL ;
...
//retrieve and use
temp = Foo::getBar();
....
delete temp ; // <- compiler did not complain (what's happend ? - has
Foo::Bar really been deleted?)
Yes, it has. Do you have any reason to believe it hasn't?
Basicaly, this is what I want to do:

1). store a copy of Bar 'safely' in Foo
2). Be able to request a ptr to Bar and use it without being able to
modify it
3). I want Foo::setBar() to be able to replace (i.e. destroy first, then
replace) the original Foo::Bar* variable

Questions:

1). How do I do that?
Well, you already are doing that. I don't see your problem.
I was doing this:

class Foo
{
public:
Foo(){ m_bar = NULL ;}

/* I need these static so I can use Bar* in some 'stand alone' C
callback functions*/
Actually, that would have to be a nonmember function declared as extern "C".
static void setBar(const Bar* b) {
if (m_bar) delete m_bar ;
m_bar = CopyOf(b) ;
Note that the above function is not exception safe. If an exception is
thrown during the execution of CopyOf(b), m_bar is invalidated.
}

static const B* getBar(void)const { return m_bar ; }
private:
Bar* m_bar ;
}


May 14 '06 #2


Rolf Magnus wrote:
<snip>

...
const Bar* temp = NULL ;
...
//retrieve and use
temp = Foo::getBar();
....
delete temp ; // <- compiler did not complain (what's happend ? - has
Foo::Bar really been deleted?)

Yes, it has. Do you have any reason to believe it hasn't?

The line 'const Bar* temp = NULL ;' declares a variable temp which is
allocated on the stack. I later on ASSIGN (not allocate) the address of
a constant ptr to temp (or atleast thats what I thought I was doing) -
and then it seems I can just go ahead and destroy the const object
pointed to by ptr. So what's the bloody use of const? It it does not
protect others from modifying your 'const' object.
Basicaly, this is what I want to do:

1). store a copy of Bar 'safely' in Foo
2). Be able to request a ptr to Bar and use it without being able to
modify it
3). I want Foo::setBar() to be able to replace (i.e. destroy first, then
replace) the original Foo::Bar* variable

Questions:

1). How do I do that?

Well, you already are doing that. I don't see your problem.

My problem is that I want to be able to hand a objet which I can create
and modify at will within the (container class), but when handing the
object to another class etc, I want to explicitly mark the object as
'handle with care' - do not modify or else ...
It would seem that I was labouring under a misaprehension about 'const'
- since the object I had decorated as a const was summarily executed as
soon as I let it out of the confines of my class - and you do not seem
suprised, and do not see what my problem is. That is what my problem is.
The fact that the compiler did not complain - and you do not seem to
find anything 'wrong' or 'unexpected' with the snippet I presented and
the behaviour I reported, is what confuses me.

So I'll ask (perhaps a little more lucidly this time)

I want to have a class that contains an object (actually a structure) -
lets call it data type A. I want the container class to have a method
which allows it to accept a new variable of data type A, and then
replaces its previous variable of data type A with the newly received one.

This same class, will receive requests by other classes, who want to use
the object. However, I do not want any class receiving this
class/structure, to be able to modify (and certainly not delete) the
received object.

This is the problem I'm trying to solve. Any pointers (no pun intended)
wll be much appreciated.
May 15 '06 #3
Bit byte wrote:
I want to have a class that contains an object (actually a structure) -
lets call it data type A. I want the container class to have a method
which allows it to accept a new variable of data type A, and then
replaces its previous variable of data type A with the newly received one.

This same class, will receive requests by other classes, who want to use
the object. However, I do not want any class receiving this
class/structure, to be able to modify (and certainly not delete) the
received object.

This is the problem I'm trying to solve. Any pointers (no pun intended)
wll be much appreciated.


A few solutions spring to mind: (1) use a reference instead of a
pointer, as Rolf suggested, since that would make it less likely (but
not impossible!) that the user would try to delete the object. (2) Use
std::tr1::shared_ptr (aka boost::shared_ptr), with which the user is
relieved of deleting the object anyway and should not try to do so. (3)
Return some other proxy object that has no public interface but is
accessible to specific friends via the attorney-client idiom (cf.
http://www.ddj.com/showArticle.jhtml...eID=184402053).

Note that you're trying to prevent the user from making mistakes.
That's good. However, you can't prevent the user from doing all sorts
of evil if s/he refuses to be civil about things.

Cheers! --M

May 15 '06 #4
On Mon, 15 May 2006 15:56:34 +0100, Bit byte wrote:
Rolf Magnus wrote:
<snip>

...
const Bar* temp = NULL ;
...
//retrieve and use
temp = Foo::getBar();
....
delete temp ; // <- compiler did not complain (what's happend ? - has
Foo::Bar really been deleted?)

Yes, it has. Do you have any reason to believe it hasn't?

The line 'const Bar* temp = NULL ;' declares a variable temp which is
allocated on the stack. I later on ASSIGN (not allocate) the address of


Are you sure that Foo:getBar() didn't allocate an object? More
importantly, how can the compiler know? Foo::getBar() may be in a
completely different translation unit altogether. And even if getBar()
does obtain the address from a container of some sort, the compiler
_still_ doesn't really know whether the pointer that was put into the
container was dynamically allocated or not.
a constant ptr to temp (or atleast thats what I thought I was doing) -
and then it seems I can just go ahead and destroy the const object
pointed to by ptr. So what's the bloody use of const? It it does not
protect others from modifying your 'const' object.
From a language perspective, destroying an object is not a "modification"
per se. It's an indication of the end of the lifetime of that object.
What you might want to do it make your destructor private and provide your
own friend function to perform disposals.
Basicaly, this is what I want to do:

1). store a copy of Bar 'safely' in Foo 2). Be able to request a ptr to
Bar and use it without being able to modify it 3). I want Foo::setBar()
to be able to replace (i.e. destroy first, then replace) the original
Foo::Bar* variable

Questions:

1). How do I do that?

Well, you already are doing that. I don't see your problem.

My problem is that I want to be able to hand a objet which I can create
and modify at will within the (container class), but when handing the
object to another class etc, I want to explicitly mark the object as
'handle with care' - do not modify or else ... It would seem that I was
labouring under a misaprehension about 'const' - since the object I had
decorated as a const was summarily executed as soon as I let it out of
the confines of my class - and you do not seem suprised, and do not see
what my problem is. That is what my problem is. The fact that the
compiler did not complain - and you do not seem to find anything 'wrong'
or 'unexpected' with the snippet I presented and the behaviour I
reported, is what confuses me.


Hand them back a const reference. If they take the address of that and
delete it, that's their problem.
So I'll ask (perhaps a little more lucidly this time)

I want to have a class that contains an object (actually a structure) -
lets call it data type A. I want the container class to have a method
which allows it to accept a new variable of data type A, and then
replaces its previous variable of data type A with the newly received
one.
This is starting to sound like an inadvisable course of action. It's
starting to sound like you want the user to construct the class, but the
container is responsible for destruction. Be careful how you go down this
path... it's an easy road to the dark side, er, memory leaks. That's one
reason why the STL containers take their own copy of the data they store.
This way the STL container controls the lifetime of the object (and if the
programmer deletes an item out from under the container, that's the
programmer's problem).
This same class, will receive requests by other classes, who want to use
the object. However, I do not want any class receiving this
class/structure, to be able to modify (and certainly not delete) the
received object.
Return a const-ref. Thus the caller shouldn't assume that it's allowed to
delete whatever that object is.
This is the problem I'm trying to solve. Any pointers (no pun intended)
wll be much appreciated.

May 15 '06 #5
Bit byte wrote:
...
const Bar* temp = NULL ;
...
//retrieve and use
temp = Foo::getBar();
....
delete temp ; // <- compiler did not complain (what's happend ? - has
Foo::Bar really been deleted?)

Yes, it has. Do you have any reason to believe it hasn't?

The line 'const Bar* temp = NULL ;' declares a variable temp which is
allocated on the stack. I later on ASSIGN (not allocate) the address of
a constant ptr to temp (or atleast thats what I thought I was doing) -
and then it seems I can just go ahead and destroy the const object
pointed to by ptr. So what's the bloody use of const? It it does not
protect others from modifying your 'const' object.


It does. However, note that destroying an object doesn't count as modifying
it.

Consider this:

#include <iostream>

class X
{
public:
X(int i) : i_(i) {}
int i_;
};

void f()
{
const X* x = new X(3);

std::cout << x->i_ << '\n';

delete x;
}

Wouldn't you say that the object pointed to by x is never modified in f()?
If, not, let's go one step further:

void f()
{
const X x = 3;
std::cout << x.i_ << '\n';
}

Has the object been modified in f() now? It was created at the beginning of
the function and destroyed at the end, just like in the previous example.
If destruction counted as modification, you could basically not define any
constants at all, because they couldn't been destroyed when they go out of
scope.
Basicaly, this is what I want to do:

1). store a copy of Bar 'safely' in Foo
2). Be able to request a ptr to Bar and use it without being able to
modify it
3). I want Foo::setBar() to be able to replace (i.e. destroy first, then
replace) the original Foo::Bar* variable

Questions:

1). How do I do that?

Well, you already are doing that. I don't see your problem.

My problem is that I want to be able to hand a objet which I can create
and modify at will within the (container class), but when handing the
object to another class etc, I want to explicitly mark the object as
'handle with care' - do not modify or else ...
It would seem that I was labouring under a misaprehension about 'const'
- since the object I had decorated as a const was summarily executed as
soon as I let it out of the confines of my class - and you do not seem
suprised, and do not see what my problem is. That is what my problem is.


I could have looked more carefully. Then I would probably have seen that you
thought destruction counted as modification.
I want to have a class that contains an object (actually a structure) -
lets call it data type A. I want the container class to have a method
which allows it to accept a new variable of data type A, and then
replaces its previous variable of data type A with the newly received one.

This same class, will receive requests by other classes, who want to use
the object. However, I do not want any class receiving this
class/structure, to be able to modify (and certainly not delete) the
received object.
Well, my question would be, why anyone would want to delete an object he
hasn't created himself and wasn't told to delete? Seriously, when I get a
pointer from some API function, I would never get the idea to delete it
unless the function's documentation explicitly tells me to do that.
Anything else is plain stupid.
This is the problem I'm trying to solve. Any pointers (no pun intended)
wll be much appreciated.


One thing you can do is return a reference to the object. However, the user
of your class can still take its address and delete the object. But with
the reference, the user might not have the idea to delete the object just
for fun.
C++ only offers features to protect against accidental errors, not about
deliberate sabotage.

May 15 '06 #6

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

Similar topics

8
by: Kelly Mandrake | last post by:
Iv'e been reading tutorials and articles describeing operator overloading as both member functions and friend functions. I don't understand however the purpose of the friend on an operator when...
15
by: Alfonso Morra | last post by:
Hi, I have some code from an example, that I want to retrofit into my project. The code from the example has the following line: SharedAppenderPtr myAppender( new...
13
by: Kelvin Moss | last post by:
Hi group, In C++ it's undefined behavior if one tries to un-const the constness of a const variable with const_cast<>. I want to know if the same holds good in C too. E.g. const char *s =...
2
by: Daniel | last post by:
I'm new to .Net and all of its abilities so I hope this makes sense. Basically I'm confused on when is the appropriate time to use web forms controls vs. regular HTML. For example in ASP...
6
by: manochavishal | last post by:
Hi , Ihave this code to show binary of an integer. #include<stdio.h> #include<stdlib.h> typedef struct binary* binaryptr; typedef struct binary { int data;
5
by: Bit Byter | last post by:
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...
6
by: porky008 | last post by:
We are still going over pseudo code and we are working on arrays right now. I am having some difficulty with the bubble sort algorithm. Can some one give me a better example than this one? I do...
7
by: Yin Zhu | last post by:
why the answer is the second ? #include <iostream.h> void fn(const char *a) { cout<<"const"<<endl; cout<<a<<endl; }
19
by: arnuld | last post by:
i am trying to understand arrays and char. Stroustrup says, this a string literal: "this is a string literal" he says it is of type /const char/. he also says, because of keeping...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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...
0
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,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
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...
0
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,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new...

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.