|
-
June 16th, 2009, 08:46 AM
#1
[RESOLVED] read only alias to a pointer
Hi,
I was wondering if there is a way to have a read only alias to a pointer.
let me explain what I am looking for.
suppose v1 is an int variable, and ptr1 is a pointer to v1.
suppose the alias to ptr1 is ptr2.
I want an alias to ptr1, in such a way that the alias doesn't modify the variable v1.
When ptr1 points to v2, the alias also must point to v2, but should not be able to modify v2.
Is this possible ?
I tried doing it, but the alias that I thought I created, isn't alias to ptr1 in the first place.
Code:
#include <iostream>
using namespace std;
int main()
{
system("clear");
int v1 = 10, v2 = 20;
cout << "&v1 = " << &v1 << "\t\tv1 = " << v1 << endl;
cout << "&v2 = " << &v2 << "\t\tv2 = " << v2 << endl;
cout << "\n\n------------\n\n";
int* ptr1 = &v1;
const int* const & ptr2 = ptr1;
cout << "&ptr1 = " << &ptr1 << "\t\tptr1 = " << ptr1 << "\t*ptr1 = " << *ptr1 << endl;
cout << "&ptr2 = " << &ptr2 << "\t\tptr2 = " << ptr2 << "\t*ptr2 = " << *ptr2 << endl;
cout << "\n\n------------\n\n";
ptr1 = &v2;
cout << "&ptr1 = " << &ptr1 << "\t\tptr1 = " << ptr1 << "\t*ptr1 = " << *ptr1 << endl;
cout << "&ptr2 = " << &ptr2 << "\t\tptr2 = " << ptr2 << "\t*ptr2 = " << *ptr2 << endl;
return(0);
}
Thanks,
Muthu
-
June 16th, 2009, 02:56 PM
#2
Re: read only alias to a pointer
Apparently, your code is a bit contradictory. You want ptr2 to be an alias of ptr1. But then you declare ptr2 as follows:
Code:
const int* const & ptr2 = ptr1;
This makes ptr2 a constant pointer to a constant integer. Therefore, ptr2 is not allowed to point to anything else after the initialization with ptr1. So it can't behave like an alias. Got it?
What you really want is that ptr2 is a non-const pointer to an constant integer.
Code:
const int* & ptr2 = ptr1;
However, this won't compile because now you're saying that ptr2 is an alias to ptr1, but ptr2 points to something constant and ptr1 doesn't. So you should declare ptr1 as a pointer to a constant too.
Code:
int* ptr1 = &v1;
//...
const int* & ptr2 = ptr1;
-
June 16th, 2009, 11:47 PM
#3
Re: read only alias to a pointer
Thanks ltcmelo, for your reply.
I have given below my views:
 Originally Posted by ltcmelo
This makes ptr2 a constant pointer to a constant integer. Therefore, ptr2 is not allowed to point to anything else after the initialization with ptr1. So it can't behave like an alias. Got it?
Lets assume if that statement worked, let me explain what I intended:
If that statement worked, ptr2 would be alias of ptr1.
Yes, ptr2 is not allowed to point to anything else after initialization.
so if ptr1 later points to a variable v2, then ptr2 would also point to the same variable v2.
ptr2 can't modify the variable it points to but ptr1 can.
And why the following statement wouldn't compile was very well explained by Speedo in the thread "const alias to a pointer"
Code:
const int* & ptr2 = ptr1;
The reason why that threw an error is explained below:
For argument sake, lets assume that was permitted by the compiler:
ptr2 would then be alias to ptr1, but ptr2 wouldn't be able to modify the variable it points to.
Lets assume there is a const variable v3.
ptr2 would be able to point to the variable v3, because ptr2 has promised the compiler not to modify that it wouldn't modify anything it points to.
Since ptr2 is an alias of ptr1, now it means that ptr1 is actually pointing to the const v3.
Now since ptr1 is a normal pointer, it is capable of modifying the variable it points to.
So ptr1 would be able to modify the const v3 (leading to undesired or unpredictable results)!!
In order to prevent that, the compiler doesn't allow that.
courtesy : Speedo (thanks to him for that explanation)
Like you pointed out the same example would work fine, if ptr1 was declared as
Code:
const int* ptr1 = &v1
But that isn't what I wanted, bcuz it would mean that ptr1 can't modify v1.
Guess it is still a mystery
Last edited by Muthuveerappan; June 16th, 2009 at 11:50 PM.
-
June 17th, 2009, 12:52 PM
#4
Re: read only alias to a pointer
This seems to work as expected when tested on MSVC ( &ptr1 = &ptr2).
On gcc it doesn't seem to work as expected ( &ptr1 != &ptr2 )
seems like a compiler specific issue, I would like to believe MSVC is correct.
Thanks,
Muthu
-
June 17th, 2009, 12:59 PM
#5
Re: read only alias to a pointer
 Originally Posted by Muthuveerappan
This seems to work as expected when tested on MSVC ( &ptr1 = &ptr2).
On gcc it doesn't seem to work as expected ( &ptr1 != &ptr2 )
Please post an updated example that illustrates what you are talking about. You should also state how does it work and how does it not work, respectively.
-
June 17th, 2009, 05:28 PM
#6
Re: read only alias to a pointer
Muthuveerappan, I wouldn't put much faith in MSVC being more correct on this point.
I'm puzzled as to why you need this feature, it rarely comes up on discussion, especially with such interest.
Perhaps you could arrange for the effect you're interested in by creating a pair of smart pointer classes. Internally they could operate on non-const references (or even pointers to pointers), but the interface would provide anything you required.
If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).
-
June 18th, 2009, 07:24 AM
#7
Re: read only alias to a pointer
I hope I have answered the questions, let me know if I am wrong or if I am not clear:
LaserLight,
-------------
I have explained below, what I wanted to achieve.
I suppose it is best to explain with the same example (scroll to top of the page for the code).
(But since you wanted a fresh example, I have pasted one more example below, along with the comments)
Below explanation corresponds to the first example (scroll to top of the page for the code)
Aim - I have a pointer ptr1 that points to v1, I would like to create an alias to ptr1, in such a way that the alias shouldn't be able to modify the variable that ptr1 points.
Suppose, ptr1 is made to point to v2, then ptr2 should also point to v2 and not be able to modify the variable it points to.
This is possible only when ptr2 is an read only alias to ptr1.
Therefore address of ptr1 should be the same as the address of ptr2
In gcc, &ptr1 is different from &ptr2, however in MSVC &ptr1 is the same as &ptr2
Same is evident when you run the above program.
Jvene
--------
The reason I wanted this, was because that it ptr2 would have restricted access, meaning it would only be a read only alias.
Yes, you are correct, the same read only access is achievable by having a pointer to a pointer (implemented in the below example and works ok), but I wanted to achieve this through a read only alias.
I didn't understand what you meant by "creating a pair of smart pointer classes", could you elaborate ?
New Example
-----------------
There is a class called Car, which contains a pointer ptr0.
Aim - A member function should return a read only alias to ptr0.
This is attempted through the function funcReturnConstRef() but on gcc it returns a temporary reference instead.
More comments are available as part of the program:
Code:
/*
There is a class Car, which has a member pointer ptr0.
I would like to return the alias of ptr0, such that the alias can't modify the variable that ptr0 points to.
If the above is acheived, when ptr0 is made to point to a new variable, then the alias would also point to the new variable.
funcReturnConstRef()
--------------------
- This function was built to do the above, but doesn't work on gcc
- In gcc the memory address of ptr0 is different from the reference returned, meaning it is not an alias to ptr0!!
funcReturnPointerToPointer()
----------------------------
- This was implemented as suggested by JVene
- This works ok
*/
#include <iostream>
using std :: cout;
using std :: endl;
class Car
{
public:
Car();
void display() const;
int*& funcReturnRef();
const int* const & funcReturnConstRef(); // Returns the const reference to the pointer
const int* const * funcReturnPointerToPointer(); //Returns a pointer to a pointer (as suggested by JVene)
private:
int* ptr0;
};
int main()
{
system("clear");
Car car1;
car1.display();
int*& ptr1 = car1.funcReturnRef(); //ptr1 would be able to modify the variable it points to
const int* const & ptr2 = car1.funcReturnConstRef(); //ptr2 wouldn't be able to modify the variable it points to
cout << "&ptr1 = " << &ptr1 << "\tptr1 = " << ptr1 << "\t\t*ptr1 = " << *ptr1 << endl;
cout << "&ptr2 = " << &ptr2 << "\tptr2 = " << ptr2 << "\t\t*ptr2 = " << *ptr2 << endl;
//Now if ptr1 is made to point to a different variable, then ptr0 would be pointing to the new variable
//and ideally ptr2 should also point to the new variable but thats not the case in gcc
//gcc
//----
//Throws a warning "returning reference to temporary"
//But the problem here is that address of ptr2 is different from the address of ptr1 (when compile/run in gcc)
const int* const * ptr3 = car1.funcReturnPointerToPointer(); //As suggested by JVene works ok.
cout << "&ptr3 = " << &ptr3 << "\tptr3 = " << ptr3 << "\t\t*ptr3 = " << *ptr3 << endl;
return(0);
}
Car :: Car()
: ptr0(new int)
{
*ptr0 = 10;
}
void Car :: display() const
{
cout << "&ptr0 = " << &ptr0 << "\tptr0 = " << ptr0 << "\t\t*ptr0 = " << *ptr0 << endl;
}
int*& Car :: funcReturnRef()
{
return(ptr0);
}
const int* const & Car :: funcReturnConstRef()
{
return(ptr0);
}
const int* const * Car :: funcReturnPointerToPointer()
{
return(&ptr0);
}
Last edited by Muthuveerappan; June 18th, 2009 at 07:27 AM.
-
June 18th, 2009, 10:47 AM
#8
Re: read only alias to a pointer
This is untested pseudo code, and I'm not entirely awake (my second coffee is brewing).
Something like this might work
Code:
template <typename T> class constalias
{
private:
int * p;
public:
constalias( T * & s ) : p( s ) {}
const T * const & operator =( T * s )
{
p = s;
return p;
}
operator const T * const & () { return p; }
};
This isn't complete, but demonstrates the following
Code:
int n = 5;
int * p( &n );
*p = 6; // legal, obviously
constalias<int> a( p ); //creates a read only alias
int d = *a; // works
*a = 7; // compile time error
Obviously you can implement variations to suit your syntax preferences, but the point is you can implement the restrictions you desire through an object representing a "kind of" smart pointer.
Actually, this is a fairly dumb pointer, now that my first sip of the second coffee is waking me up, but I think it brings a new point to the thread.
You might prefer something like
Code:
template <typename T> class constalias
{
private:
int ** p;
public:
constalias( T * & s ) : p( &s ) {}
const T * const & operator =( T *& s )
{
p = &s;
return *p;
}
operator const T * const & () { return *p; }
};
Such that
Code:
int n;
int r;
int * p( &n );
constalias<int> a( p );
n = 5;
r = 10;
*p = 6;
int d = *a;
p = &r;
d = *a;
At which point d is 10.
Last edited by JVene; June 18th, 2009 at 11:22 AM.
If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).
-
June 19th, 2009, 10:07 AM
#9
Re: read only alias to a pointer
Hi JVene,
Thanks for that reply, seems to be something that I never thought of.
could you explain what the following line means:
Code:
operator const T * const & () { return *p; }
1) I mean what is the operator ?
2) what is the return type ?
-
June 19th, 2009, 10:12 AM
#10
Re: read only alias to a pointer
 Originally Posted by Muthuveerappan
1) I mean what is the operator ?
2) what is the return type ?
That is a conversion function that allows one to convert an object of type constalias<T> to a reference to a const pointer to a const T *.
-
June 19th, 2009, 10:50 AM
#11
Re: read only alias to a pointer
Thanks laserlight, but I am a little confused and am not sure I fully understand.
I have summed up what I have understood, pls correct me if I am wrong:
I just feel I would understand better, if we can break up the statement.
Let me know if "breaking up into smaller questions" is absurd or incorrect.
Code:
Question Answer
----------- --------------------
1) what is the operator here ? ??
2) return type ? const T * const &
3) how is it invoked (example)? ??
By logging messages I realized that function/operator is not called when the following statement is executed:
Code:
constalias<int> a( p );
It gets called when the following statement is executed (I just added the following statement):
-
June 19th, 2009, 02:47 PM
#12
Re: read only alias to a pointer
The operator is called a conversion operator. It's a formal means of providing the compiler with a method to perform an automatic conversion. For example, if I have a string and I want to automatically support the conversion of that to a float, I can provide a conversion operator that returns a float - using something like atof inside the function to perform the conversion.
It is invoked when the compiler is presented with a situation where it would normally issue an error because the conversion isn't possible. Before it does that, however, it searches the object for conversion functions, and if one qualifies it calls the conversion function.
d = *a;
d, being an integer, can't be assigned to a constalias<int>, or as this statement indicates, what's stored at the object - which wouldn't really make much sense because the types aren't compatible. This would result in an error, except...
There is a conversion operator available that returns a const T * const &, where T is an int. In this case, the * in front of the a would make sense, and the compiler calls for the conversion - at which point a now looks like an integer pointer (const though it is), the * in front of that now no longer fires an error.
Similarly:
*a = d;
Would start out performing a similar problem, but here the compiler can't find a solution. First, there's no way a constalias<int> can accept an integer (and we haven't provided any such way). However, the * in front of the a makes even less sense, except for the conversion operator.
The compiler will check for it, but it realizes that even though it might make sense if the conversion were to a plain int *, since the conversion is for a const T * const &, the const will cause the compiler to generate an error - the error should read as though a were an int * to a const int, complaining about the constness of the assignment, not the meaningless notion of a * operator in front of a constalias<int>.
constalias<int> a( p );
In this case, this is simply the construction of a constalias<int>, which accepts an int *&. No conversion is required.
Last edited by JVene; June 20th, 2009 at 01:06 AM.
If my post was interesting or helpful, perhaps you would consider clicking the 'rate this post' to let me know (middle icon of the group in the upper right of the post).
-
June 19th, 2009, 05:49 PM
#13
Re: read only alias to a pointer
Hi Muthuveerappan,
It is strange that gcc and MSVC give different results for this!
I think that as an alternative you can use references to serve your purpose :
(note you can modify the object through the non-const reference,
but not through the const reference)
Code:
#include <iostream>
using namespace std;
int main()
{
int v1 = 10, v2 = 20;
cout << "&v1 = " << &v1 << "\t\tv1 = " << v1 << endl;
cout << "&v2 = " << &v2 << "\t\tv2 = " << v2 << endl;
cout << "\n\n------------\n\n";
int& ref1 = v1;
const int & ref2 = ref1;
cout << "ref1 = " << ref1 << endl;
cout << "ref2 = " << ref2 << endl;
cout << "\n\n------------\n\n";
ref1 = v2;
cout << "ref1 = " << ref1 << endl;
cout << "ref2 = " << ref2 << endl;
//ref1 = 42; //*********ALLOWED*************
//ref2 = 44; //*********COMPILER ERROR******
return(0);
}
This works in both environments and yields the same results.
The output in both gcc and MSVC is :
Code:
&v1 = 0012FF60 v1 = 10
&v2 = 0012FF54 v2 = 20
------------
ref1 = 10
ref2 = 10
------------
ref1 = 20
ref2 = 20
-
June 20th, 2009, 12:35 AM
#14
Re: read only alias to a pointer
Thanks for the reply Artella, I agree with you that it works for a read only alias to a variable.
We were trying to get a read only alias to a pointer.
Except with the pointer, there is just one more extra step to cover (explained at the beginning of this thread)
"const int * const &" is a solution but it seems to be compiler specific, but there are other ways to accomplish the same, though it might not be as straight forward as "const int * const &":
The following were suggested by JVene
1) pointer to pointer - using a class and a member function to do the same
2) a template class and a more generic and more user friendly implementation of pointer to pointer approach
Last edited by Muthuveerappan; June 20th, 2009 at 12:37 AM.
-
June 20th, 2009, 07:43 AM
#15
Re: read only alias to a pointer
Or as another alternative, you could just have a single pointer to a const, and then use const_cast to whenever you want to modify. For example :
Code:
#include <iostream>
using namespace std;
int main(void)
{
int v1 = 10, v2 = 20;
cout << "v1 = " << v1 << endl;
cout << "v2 = " << v2 << endl;
cout << "\n\n------------\n\n";
const int* ptr = &v1;
cout << "*ptr = " << *ptr << endl;
cout << "\n\n------------\n\n";
*const_cast<int *>(ptr) = v2;
//*ptr = v2;//This is NOT ALLOWED
cout << "*ptr = " << *ptr << endl;
return 0;
}
which outputs :
Code:
v1 = 10
v2 = 20
------------
*ptr = 10
------------
*ptr = 20
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|