By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,381 Members | 1,561 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,381 IT Pros & Developers. It's quick & easy.

Why can you delete a const pointer?

P: n/a
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();

Please, enlighten me!

Dec 28 '05 #1
Share this Question
Share on Google+
21 Replies


P: n/a
Roman Werpachowski wrote:
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();


Because the constness of a pointer/object/reference has nothing to do
with allocation, deletion, construction or destruction.

template <class T>
void f()
{
// make sure the T never changes
const T* t = new T;

// huh.. what do I do here to delete t?
}
Jonathan

Dec 28 '05 #2

P: n/a
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?

Dec 28 '05 #3

P: n/a
Roman Werpachowski wrote:
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?


No, except by using a smart pointer or a handle.

If you absolutely need a raw pointer, you could define an operator
delete() in the class and make it private. This would catch a "delete
p;" but would make it impossible to create objects directly (new T).
Note that both these restrictions could be foiled by using the global
operators.

Why give the pointer in the first place anyways? People will be much
less tempted to delete the object if you give a reference.

Jonathan

Dec 28 '05 #4

P: n/a

Roman Werpachowski escreveu:
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?


If you return a reference to the pointed to object, the user of your
class can't delete it because you can't delete a reference.

const T & A::f() const
{
return *t;
}

HTH,

Marcelo Pinto.

Dec 28 '05 #5

P: n/a
Marcelo Pinto wrote:
Roman Werpachowski escreveu:
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?


If you return a reference to the pointed to object, the user of your
class can't delete it because you can't delete a reference.

const T & A::f() const
{
return *t;
}


Perhaps, but you can delete the object at its address:

void f(A& a)
{
T& t(a.f());
delete &t;
}

But as I said, users will be much less tempted to do that, compared to
returning by address.
Jonathan

Dec 28 '05 #6

P: n/a

"Jonathan Mcdougall" <jo***************@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Roman Werpachowski wrote:
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();


Because the constness of a pointer/object/reference has nothing to do
with allocation, deletion, construction or destruction.


Not so. Deletion is ok, but not allocation (except initialization).

There are two things going on in the OP's code that affect its "legality".

First, it's an initialization, which is legal for const pointers.

Second, he does not have constant pointers at all! That code shows a
pointer to const double, _not_ a const pointer to double. It's perfectly
legal to assign to a pointer-to-const. It's what it's pointing to that's
constant.

Consider:

double * x = new double;
const double * p = NULL; // legal - just an initialization
p = x; // still ok, since p is not a const pointer (but rather a
pointer-to-const)
*p = 1.2; // oops! illegal = assigning to const double

const double * x1 = new double; // legal - just an initialization
double * const p1 = NULL; // also legal - just an initialization
p1 = x; // oops! illegal - assigning to const pointer
-Howard


Dec 28 '05 #7

P: n/a

"Howard" <al*****@hotmail.com> wrote in message
news:_W*********************@bgtnsc04-news.ops.worldnet.att.net...

"Jonathan Mcdougall" <jo***************@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Roman Werpachowski wrote:
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();
Because the constness of a pointer/object/reference has nothing to do
with allocation, deletion, construction or destruction.


Not so. Deletion is ok, but not allocation (except initialization).

There are two things going on in the OP's code that affect its "legality".

First, it's an initialization, which is legal for const pointers.

Second, he does not have constant pointers at all! That code shows a
pointer to const double, _not_ a const pointer to double. It's perfectly
legal to assign to a pointer-to-const. It's what it's pointing to that's
constant.

Consider:

double * x = new double;
const double * p = NULL; // legal - just an initialization
p = x; // still ok, since p is not a const pointer (but rather a
pointer-to-const)
*p = 1.2; // oops! illegal = assigning to const double

const double * x1 = new double; // legal - just an initialization
double * const p1 = NULL; // also legal - just an initialization
p1 = x; // oops! illegal - assigning to const pointer


(BTW, I meant that to be p1 = x1;)


Forgot to show this one (the allocation of a const pointer):

double * const p2 = NULL; // legal - just an initialization
p2 = new double; // oops! illegal - assigning to const pointer

The allocation of p2 would be fine as an initialization, but not as an
assignment, because it's const.

-Howard


Dec 28 '05 #8

P: n/a
Howard wrote:
"Jonathan Mcdougall" <jo***************@gmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Roman Werpachowski wrote:
I can't understand this:

double * x = new double;
const double * p = x;
delete p;

works. Why am I allowed to delete a const pointer? On the same note:
why am I allowed to do this:

class probna {
//
};

probna pr;
const probna& ref_pr = p;

ref_pr.~probna();


Because the constness of a pointer/object/reference has nothing to do
with allocation, deletion, construction or destruction.


Not so. Deletion is ok, but not allocation (except initialization).


By "allocation", I meant initialization by a newly allocated object,
not changing a pointer value (which was not the point).
Jonathan

Dec 28 '05 #9

P: n/a
Howard napisal(a):
const double * x1 = new double; // legal - just an initialization
double * const p1 = NULL; // also legal - just an initialization
p1 = x; // oops! illegal - assigning to const pointer


Is

delete p1;

legal or not?

Dec 28 '05 #10

P: n/a
Jonathan Mcdougall napisal(a):
Why give the pointer in the first place anyways? People will be much
less tempted to delete the object if you give a reference.


I wanted to use references first, but got bogged down on such code:

class pipek {
};

class klasa {
private:
pipek& p_;
public:
void set_p(pipek& p)
{
p_ = p;
}
};

class mazut {
private:
pipek p_;
public:
pipek& get_p()
{
return p_;
}
};

int main()
{
klasa k1;
mazut m1;

k1.set_p( m1.get_p() );
}

it compiles with error:

test.cc: In function `int main()':
test.cc:25: error: structure `k1' with uninitialized reference members

while assigning a pointer to a pointer works just fine.

Dec 28 '05 #11

P: n/a
On Wed, 28 Dec 2005 13:30:23 -0800, Roman Werpachowski wrote:
So there is no way to make sure that someone does not delete my member
object, if I decide to give access to it via a reference/pointer?


Make the destructor private, accessible only by a member function or
friends of the class.

- Jay
Dec 28 '05 #12

P: n/a
Roman Werpachowski wrote:
I wanted to use references first, but got bogged down on such code:

class pipek {
};

class klasa {
private:
pipek& p_;
public:
void set_p(pipek& p)
{
p_ = p;
}
};

class mazut {
private:
pipek p_;
public:
pipek& get_p()
{
return p_;
}
};

int main()
{
klasa k1;
mazut m1;

k1.set_p( m1.get_p() );
}

it compiles with error:

test.cc: In function `int main()':
test.cc:25: error: structure `k1' with uninitialized reference members

while assigning a pointer to a pointer works just fine.


I think you missed something about references.
Reference is an alternate name for existing object (a synonim).
So, what should become clear now, reference must always refer to
existing object.

The problem is that in your class klasa default constructor does not
initializes reference. So, you have to provide initializetion
explicitely passing existing object of class of pipek as a constructor
parameter.

Cheers
--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 28 '05 #13

P: n/a
So I should store the pointer internally and use references in the
interface?

Dec 28 '05 #14

P: n/a
Roman Werpachowski wrote:
So I should store the pointer internally and use references in the
interface?


Hm, it depends on your requirements and assumptions.
You can have member as value or as pointer:

class A
{
myclass data; // data is initialized by default constructor of myclass
}

class B
{
myclass* pdata; // here you pointer
public:
B() : pdata(0) {} // pdata is nullpointer by default
}

In class A you always play with instance of myclass,
because the lifetime of data is determined by lifetime of instance of A.

In class B situation is different. pdata may or may not point to any
instance of myclass during whole lifetime of A.

Now, you have to be aware that client of object of B may get nullpointer
as a result of query for pdata (e.g. using accessor myclass* getData()
const;) or may get pointer pointing to existing instance of myclass.
Here it comes more complex than when working with class A.

Simply, you have to thing about the ownership issues and if you want to
allow ownership transfer or not, etc.

Cheers
--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 28 '05 #15

P: n/a
I would like the myclass member to be a sort of "plugin" which the user
of the class B can fiddle with during the lifetime of the instance of B
(change it several times, for example). It seems that the internal
pointer is a better choice, isn't it?

Dec 28 '05 #16

P: n/a
I would like the myclass member to be a sort of "plugin" which the user
of the class B can fiddle with during the lifetime of the instance of B
(change it several times, for example). It seems that the internal
pointer is a better choice, isn't it?

Thanks for your patience, folks ;-)

Dec 28 '05 #17

P: n/a
Roman Werpachowski wrote:
I would like the myclass member to be a sort of "plugin" which the user
of the class B can fiddle with during the lifetime of the instance of B
(change it several times, for example). It seems that the internal
pointer is a better choice, isn't it?


Yes, it is.
Plugin will be loaded/unloaded so it's lifetime is not staticaly set up.
Cheers

--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 28 '05 #18

P: n/a

"Roman Werpachowski" <ro****************@gmail.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
Howard napisal(a):
const double * x1 = new double; // legal - just an initialization
double * const p1 = NULL; // also legal - just an initialization
p1 = x; // oops! illegal - assigning to const pointer


Is

delete p1;

legal or not?


Yes, it's legal. You have to be able to delete, even const pointers, or
else you'd have a leak every time you initialize one via new.

-Howard
Dec 28 '05 #19

P: n/a
Your answers cleared up the confusion in my head. Thanks!

Dec 29 '05 #20

P: n/a
Roman Werpachowski wrote:
Your answers cleared up the confusion in my head. Thanks!


For me too. I was a bit surprised about such obvious issue as memory
leaks. From time to time I'm surprised how obvious things can hide
and seem so unobvious :-)

Cheers
--
Mateusz Łoskot
http://mateusz.loskot.net
Dec 29 '05 #21

P: n/a
you got a mistake, p is not a const pointer, *p is a const double
just-so-so

Dec 29 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.