 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
tthunder@gmx.de Guest
|
Posted: Mon Dec 12, 2005 1:59 pm Post subject: Prevent calling operator-> as function |
|
|
Hi @all,
I have a classes like this:
// -------------------
class foo
{
public:
void doSomething(){}
};
class myClass
{
private:
foo *aFoo;
public:
foo *operator->(){return aFoo;}
}
// -------------------
Now I can do this...
myClass aClass;
aClass->doSomething();
But there is a design leak (in my concrete concept), because someone
can get the pointer to foo directly:
myClass aClass;
foo *aFoo = aClass.operator->();
Is there a way to prohibit this?
Greetings and thanks,
Kirsten
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
mzdude Guest
|
Posted: Mon Dec 12, 2005 4:55 pm Post subject: Re: Prevent calling operator-> as function |
|
|
[email]tthunder (AT) gmx (DOT) de[/email] wrote:
| Quote: | Hi @all,
I have a classes like this:
// -------------------
class foo
{
public:
void doSomething(){}
};
class myClass
{
private:
foo *aFoo;
public:
foo *operator->(){return aFoo;}
}
|
When using containment, it's usually a bad idea to return the address
of private variables. You should re-implement those functions that you
want to expose.
class myClass
{
public:
void doSomething()
{ return aFoo->doDomething(); }
private:
foo *aFoo;
};
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
tthunder@gmx.de Guest
|
Posted: Mon Dec 12, 2005 7:52 pm Post subject: Re: Prevent calling operator-> as function |
|
|
Of course, I know
But I have a very special task for the operator, so I really need the
feature I mentioned.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
benben Guest
|
Posted: Tue Dec 13, 2005 5:14 pm Post subject: Re: Prevent calling operator-> as function |
|
|
[email]tthunder (AT) gmx (DOT) de[/email] wrote:
| Quote: | Of course, I know
But I have a very special task for the operator, so I really need the
feature I mentioned.
|
Well why shouldn't user call foo::doSomething directly?
You can first hide foo from user's visibility by nesting it as a private
part of something.
Then you can wrap it up with another class:
class foo_wrapper: private foo{
public:
void doSomething(){
//... some prefix code
foo::doSomething();
//... some postfix code
}
};
That done, change myClass::operator() to:
foo_wrapper* myClass::operator()(void);
I assume it is ok to expose foo::doSomething this way.
Ben
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Old Wolf Guest
|
Posted: Tue Dec 13, 2005 6:09 pm Post subject: Re: Prevent calling operator-> as function |
|
|
[email]tthunder (AT) gmx (DOT) de[/email] wrote:
| Quote: | Now I can do this...
myClass aClass;
aClass->doSomething();
But there is a design leak (in my concrete concept), because someone
can get the pointer to foo directly:
myClass aClass;
foo *aFoo = aClass.operator->();
Is there a way to prohibit this?
|
Not exactly, but you can make it difficult. Here's a program I
wrote based on an idea by Andrei Alexandrescu:
#include <iostream>
#define HEEHEEHAHA 4
template<int N, typename T> struct Proxy {
Proxy(T *p): p(p) {}
Proxy<N-1,T> operator->() { return Proxy<N-1,T>(p); }
private: T *p;
};
template<typename T> struct Proxy<2, T> {
Proxy(T *p): p(p) {}
T *operator->() { return p; }
private: T *p;
};
struct foo
{
void print() { std::cout << "Foo " << std::endl; }
};
class MyClass
{
foo *ptr;
public:
Proxy() { return ptr; }
MyClass(): ptr(new foo) {}
~MyClass() { delete ptr; }
};
int main()
{
MyClass m;
m->print();
// get raw pointer
foo *ptr = m.operator->().operator->().operator->().operator->();
}
Now, just change HEEHEEHAHA from 4 to 100 .. then the
caller will have to do a lot of typing to get the raw pointer :)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
nick Guest
|
Posted: Tue Dec 13, 2005 6:13 pm Post subject: Re: Prevent calling operator-> as function |
|
|
class foo
{
public:
void doSomething(){}
};
class fooRef {
public:
foo* operator->(){return f;}
private:
friend class myClass;
fooRef() {}
fooRef(foo* f_) : f(f_) {}
fooRef(const fooRef&) {}
foo *f;
};
class myClass
{
private:
fooRef aFoo;
public:
myClass(){}
fooRef operator->(){return aFoo;}
};
int main() {
myClass aClass;
aClass->doSomething();
fooRef f = aClass.operator->(); //Error
foo* ff = aClass.operator->(); //Error
//But this work
foo* ff = aClass.operator->().operator->();
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Samee Zahur Guest
|
Posted: Tue Dec 13, 2005 6:34 pm Post subject: Re: Prevent calling operator-> as function |
|
|
I ... don't get it. You say you really need the operator->(), but
cannot let the user get a pointer. Well, let's see, if the user does
get the pointer, it will be able to perform exactly the same operations
it would have done directly with operator->() ... no more. I mean, if
the user can do ptr->dothis(), then the user could already have done
obj->dothis(). What exactly is it that you are trying to achieve by
allowing operator->() without exposing pointers?
Samee
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
jsnX Guest
|
Posted: Tue Dec 13, 2005 10:19 pm Post subject: Re: Prevent calling operator-> as function |
|
|
what is your task? i am really curious to know how this came up...
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Earl Purple Guest
|
Posted: Wed Dec 14, 2005 12:53 pm Post subject: Re: Prevent calling operator-> as function |
|
|
| Quote: | myClass aClass;
foo *aFoo = aClass.operator->();
Is there a way to prohibit this?
|
They cannot modify your foo pointer. They can modify what it points to,
but that's because you return a non-const pointer. But then they will
want to be able to call non-const methods. operator= if not disabled
(by declaring it private) is a non-const method just like any other so
they could do aClass->operator=( aDifferentFoo ); even without getting
the pointer directly.
Depending on the nature of the foo class, the class might not be foo
but a derivative of foo. If you have control over such a class you can
limit this way what the user can do.
You could also return a foo-wrapper that does not expose the foo itself
but only the limited features you wish to expose.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
mzdude Guest
|
Posted: Wed Dec 14, 2005 3:45 pm Post subject: Re: Prevent calling operator-> as function |
|
|
Old Wolf wrote:
| Quote: | Not exactly, but you can make it difficult. Here's a program I
wrote based on an idea by Andrei Alexandrescu:
#include <iostream
#define HEEHEEHAHA 4
template
Proxy(T *p): p(p) {}
Proxy<N-1,T> operator->() { return Proxy<N-1,T>(p); }
private: T *p;
};
template<typename T> struct Proxy<2, T> {
Proxy(T *p): p(p) {}
T *operator->() { return p; }
private: T *p;
};
struct foo
{
void print() { std::cout << "Foo " << std::endl; }
};
class MyClass
{
foo *ptr;
public:
Proxy() { return ptr; }
MyClass(): ptr(new foo) {}
~MyClass() { delete ptr; }
};
int main()
{
MyClass m;
m->print();
// get raw pointer
foo *ptr = m.operator->().operator->().operator->().operator->();
}
Now, just change HEEHEEHAHA from 4 to 100 .. then the
caller will have to do a lot of typing to get the raw pointer :)
|
Clever.
But the question is why do you want to hide the pointer?
If you don't trust the users, then this won't work. Since they have the
header file, they'll just modify HEEHEEHAHA to 1 and then you haven't
solved anything. If the returned pointer is transient and isn't stable
over time, then a proxy class doesn't solve the problem either. The
proxy will eventually point to an invalid object, and even the original
doSomething() will fail.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|