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

overloading global dereference operator?

Hi!

I'm diving into the some more ++ specific aspects of c++ (and finally
accepting that c++ is more than "a plus added to c" :), so that means
using namespaces, templates, std::strings, lists, vectors, operator
overloading and what not.. And i was wondering if there is a way to
override the global dereference operator, so to be able to check the
address that one tries to dereference. This gives the ability to throw
an exception when one would try to dereference NULL for instance.

I have tried several different ways to do it, but gcc doesn't like what
i'm asking of him...

This attempt is the most reasonable to me:
43 template<class T> T& operator * (T* ptr)
44 {
45 if (!ptr)
46 throw EAccessViolation();
47
48 return (*ptr);
49 }
(sorry about the line numbers.. Just the vim settings on my console)

Even though this seems right to me, g++ gives me the following
complaint when i compile that like thus:
[tim@server tests]$ g++ -Wall -o test operatornew.cpp > c.log 2>&1
[tim@server tests]$ cat c.log
operatornew.cpp:44: error: `T& operator*(T*)' must have an argument of
class or
enumerated type
[tim@server tests]$

Could it be that the compiler gets confused and/or thinks that i want
to overide the multiply operator? Or am i just beeing totaly clueless
here? :)

I have searched for this for what feels like all around the net, but i
can't seem to find anything like it. Everything that comes up about
dereference operator overloading is the operator->() for inside a
class.. I have also tried putting this global, which naturaly didn't
work becouse -> is obviously only used for members..

Can anyone give me a lead on this and/or provide some example code?
Tnx!

Tim.

Dec 4 '05 #1
6 5360
"TuxC0d3" <ti*@almerefriends.net> wrote in message
news:11*********************@g49g2000cwa.googlegro ups.com
Hi!

I'm diving into the some more ++ specific aspects of c++ (and finally
accepting that c++ is more than "a plus added to c" :), so that means
using namespaces, templates, std::strings, lists, vectors, operator
overloading and what not.. And i was wondering if there is a way to
override the global dereference operator, so to be able to check the
address that one tries to dereference. This gives the ability to throw
an exception when one would try to dereference NULL for instance.

I have tried several different ways to do it, but gcc doesn't like
what i'm asking of him...

This attempt is the most reasonable to me:
43 template<class T> T& operator * (T* ptr)
44 {
45 if (!ptr)
46 throw EAccessViolation();
47
48 return (*ptr);
49 }
(sorry about the line numbers.. Just the vim settings on my console)

Even though this seems right to me, g++ gives me the following
complaint when i compile that like thus:
[tim@server tests]$ g++ -Wall -o test operatornew.cpp > c.log 2>&1
[tim@server tests]$ cat c.log
operatornew.cpp:44: error: `T& operator*(T*)' must have an argument of
class or
enumerated type
[tim@server tests]$

Could it be that the compiler gets confused and/or thinks that i want
to overide the multiply operator? Or am i just beeing totaly clueless
here? :)

I have searched for this for what feels like all around the net, but i
can't seem to find anything like it. Everything that comes up about
dereference operator overloading is the operator->() for inside a
class.. I have also tried putting this global, which naturaly didn't
work becouse -> is obviously only used for members..

Can anyone give me a lead on this and/or provide some example code?
Tnx!


You can't overload operators that involve only built in types. At least one
operand must be of class/struct/enum type. Pointers are considered built in
types, even if they point to user-defined types. Thus you cannot overload
any operator that works exclusively on pointers. For example, the following
won't compile:

#include <iostream>

struct S
{};

void operator+(S*lptr, S*rptr)
{
std::cout << "New plus pointers operator\n";
}

--
John Carson

Dec 4 '05 #2
Hmm, ok that sounds reasonable..

However, it would be nice if it could be made to work, for instance by
some kind of class-with-operator-overloading technique.. (Like wrapping
a pointer inside a class to make it a "smart" pointer, or such a
thing..)
That might make it work a decent bit slower, but when building in debug
mode, it could provide me with a lot of helpful information...

I'm thinking about something like
template(class T) class ptr
{
T* m_ptr;
public:
//... add default constructor, copy ctor and operator=, etc here
T& operator*()
{
if (!m_ptr)
throw EAccessViolation();
return *m_ptr;
}
};

Wouldn't something like that be able to solve it as well, or am i
probably thinking along the wrong lines? (for instance that this
wouldn't give me an object which acts like a pointer, but gives me a
ptr::* (or something like that))

Don't be afraid to speak tech by the way.. I've already got my pretty
little callback technique (based on a class with () operator
overloading, a template constructor and pointer-to-memberfunction)
working like a charm in only a couple of hours with almost no
experience in operator overloading, templates, etc etc. :-) (Though i
do understand quite some things about working with pointers)

--
Tim.

Dec 4 '05 #3
"TuxC0d3" <ti*@almerefriends.net> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com
Hmm, ok that sounds reasonable..

However, it would be nice if it could be made to work, for instance by
some kind of class-with-operator-overloading technique.. (Like
wrapping a pointer inside a class to make it a "smart" pointer, or
such a thing..)
That might make it work a decent bit slower, but when building in
debug mode, it could provide me with a lot of helpful information...

I'm thinking about something like
template(class T) class ptr
{
T* m_ptr;
public:
//... add default constructor, copy ctor and operator=, etc here
T& operator*()
{
if (!m_ptr)
throw EAccessViolation();
return *m_ptr;
}
};

Wouldn't something like that be able to solve it as well, or am i
probably thinking along the wrong lines? (for instance that this
wouldn't give me an object which acts like a pointer, but gives me a
ptr::* (or something like that))


Sure, wrapping a pointer in a class will give you something pretty close to
what you want. The following (quickly composed) class seems to work OK,
though it is still missing some needed operators (I haven't defined a copy
constructor or assignment operator since the compiler supplied ones seem
adequate):

#include <iostream>
using namespace std;

struct S
{
int x;
};
class EAccessViolation
{};

template<class T> class ptr
{
T* m_ptr;
public:
ptr() : m_ptr(0)
{}
ptr(T *rawptr) : m_ptr(rawptr)
{}
bool operator==(ptr &rhs)
{
return m_ptr == rhs.m_ptr;
}
T*operator->() const
{
if (!m_ptr)
throw EAccessViolation();
return m_ptr;
}
T& operator*() const
{
if (!m_ptr)
throw EAccessViolation();
return *m_ptr;
}
};
int main()
{
S s1,s2;
ptr<S> p1=&s1, p2, p3;

// p1 is initialised but p2 is not so should be able to
// dereference p1 OK but get an exception from p2

p3 = p1;
if(p1==p3)
cout << "p1 and p3 are equal\n";
else
cout << "p1 and p3 are unequal\n";
try
{
p1->x = 5;
cout << "Dereference of p1 successful\n";
}
catch(EAccessViolation&)
{
cout << "Access violation for p1\n";
}
try
{
p2->x = 5;
cout << "Dereference of p2 successful\n";
}
catch(EAccessViolation&)
{
cout << "Access violation for p2\n";
}
try
{
s2 = *p1;
cout << "Dereference successful for p1\n";
}
catch(EAccessViolation&)
{
cout << "Access violation for p1\n";
}
try
{
s2 = *p2;
cout << "Dereference successful for p2\n";
}
catch(EAccessViolation&)
{
cout << "Access violation for p2\n";
}
}

Note that a wrapped pointer is never quite the same as a raw pointer.
Consider:

struct Test
{
Test(int *pint)
{}
};

void foo(const Test &test)
{}

int main()
{
int *pint1;
foo(pint1); // will compile

ptr<int> pint2;
foo(pint2); // won't compile since two user defined
//conversions required
}
--
John Carson

Dec 4 '05 #4
John Carson wrote:
"TuxC0d3" <ti*@almerefriends.net> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com
Hmm, ok that sounds reasonable..

However, it would be nice if it could be made to work, for instance by
some kind of class-with-operator-overloading technique.. (Like
wrapping a pointer inside a class to make it a "smart" pointer, or
such a thing..)
That might make it work a decent bit slower, but when building in
debug mode, it could provide me with a lot of helpful information...

I'm thinking about something like
template(class T) class ptr
{
T* m_ptr;
public:
//... add default constructor, copy ctor and operator=, etc here
T& operator*()
{
if (!m_ptr)
throw EAccessViolation();
return *m_ptr;
}
};

Wouldn't something like that be able to solve it as well, or am i
probably thinking along the wrong lines? (for instance that this
wouldn't give me an object which acts like a pointer, but gives me a
ptr::* (or something like that))
Sure, wrapping a pointer in a class will give you something pretty close to
what you want. The following (quickly composed) class seems to work OK,
though it is still missing some needed operators (I haven't defined a copy
constructor or assignment operator since the compiler supplied ones seem
adequate):

#include <iostream>
using namespace std;

struct S
{
int x;
};
class EAccessViolation
{};

template<class T> class ptr
{
T* m_ptr;
public:
ptr() : m_ptr(0)
{}
ptr(T *rawptr) : m_ptr(rawptr)
{}
bool operator==(ptr &rhs)
{
return m_ptr == rhs.m_ptr;
}
T*operator->() const
{
if (!m_ptr)
throw EAccessViolation();
return m_ptr;
}
T& operator*() const
{
if (!m_ptr)
throw EAccessViolation();
return *m_ptr;
}


Some implementations would elect to add these methods:

operator T*()
{
return m_ptr;
}

operator const T*() const
{
return m_ptr;
} };
Note that a wrapped pointer is never quite the same as a raw pointer.
Consider:

struct Test
{
Test(int *pint)
{}
};

void foo(const Test &test)
{}

int main()
{
int *pint1;
foo(pint1); // will compile

ptr<int> pint2;
foo(pint2); // won't compile since two user defined
//conversions required


With the conversion methods added, there is one user-defined conversion
from ptr<int> to int* so the above function call will compile and work
correctly.

Although adding these conversion methods makes the smart pointer
virtually indistinguishable from a raw pointer, it can cause problems
if the smart pointer is maintaining a reference count. The implicit
conversion allows the smart pointer to be assigned to a raw pointer
without incrementing the reference count. For this (and other reasons)
an implicit conversion to the corresponding raw pointer is usually not
provided, or done so conditionally. And any client wanting to perform
such a conversion must do so explicitly.

Greg

Dec 5 '05 #5
"Greg" <gr****@pacbell.net> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com
John Carson wrote:

Note that a wrapped pointer is never quite the same as a raw pointer.
Consider:

struct Test
{
Test(int *pint)
{}
};

void foo(const Test &test)
{}

int main()
{
int *pint1;
foo(pint1); // will compile

ptr<int> pint2;
foo(pint2); // won't compile since two user defined
//conversions required
}


Some implementations would elect to add these methods:

operator T*()
{
return m_ptr;
}

operator const T*() const
{
return m_ptr;
}

With the conversion methods added, there is one user-defined
conversion from ptr<int> to int* so the above function call will
compile and work correctly.


Actually, no. In fact my comments implicitly assumed exactly that operator
(I should have made this explicit). foo does not take a int * argument; it
takes a reference to Test. Thus there are two conversions required:

1. int<ptr> to int *
2. int * to Test

Accordingly, the code will not compile.

Of course, one might not want the conversion from int<ptr> to Test, but that
is another issue. The issue at hand is the equivalence of int * and ptr<int>
and the foo function illustrates a non-equivalence.

--
John Carson
Dec 5 '05 #6
"John Carson" <jc****************@netspace.net.au> wrote in message
news:43***********************@un-2park-reader-01.sydney.pipenetworks.com.au
Thus there are two
conversions required:
1. int<ptr> to int *
2. int * to Test


That should be ptr<int>, not int<ptr>

--
John Carson
Dec 6 '05 #7

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

Similar topics

2
by: victor75040 | last post by:
Before you all start flaming me, I am not a student and this is not for any homework. Just someone learing c++ on their own. I am now up to the chapter in my book that describes operator...
18
by: Joe Seigh | last post by:
Is there a good write on this. The textbooks I have fluff over on this? Specifically, I trying to dereference with 2 levels of type conversion not 1, i.e. X<T> -> z => Y<T> -> z => T* ->...
3
by: Robert Wierschke | last post by:
Hi I want to overload the operator<< for a class Vector. class Vector { double x; double y; double z;
1
by: Zachary Turner | last post by:
I'm having trouble overloading the global operator new and delete. I want to do this for debugging purposes to trace allocations and deallocations. What I have is #ifdef _DEBUG //...
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...
3
by: md | last post by:
Hi, the following code is working for static objects. ie the statement IntArray x(20); my problem is i want to use this overloading operator for dynamically created objects...
3
by: Lighter | last post by:
The C++ Standard Doesn't Permit Overloading new and delete? In the 13.5 of The C++ standard (ISO/IEC 14882, 1998), I cannot find the specification on overloading the operators new and delete;...
5
by: Jerry Fleming | last post by:
As I am newbie to C++, I am confused by the overloading issues. Everyone says that the four operators can only be overloaded with class member functions instead of global (friend) functions: (), ,...
3
by: y-man | last post by:
Hi, I am trying to get an overloaded operator to work inside the class it works on. The situation is something like this: main.cc: #include "object.hh" #include "somefile.hh" object obj,...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...

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.