C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Prevent calling operator-> as function

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
tthunder@gmx.de
Guest





PostPosted: Mon Dec 12, 2005 1:59 pm    Post subject: Prevent calling operator-> as function Reply with quote



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





PostPosted: Mon Dec 12, 2005 4:55 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote



[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





PostPosted: Mon Dec 12, 2005 7:52 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote



Of course, I know Wink
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





PostPosted: Tue Dec 13, 2005 5:14 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote

[email]tthunder (AT) gmx (DOT) de[/email] wrote:
Quote:
Of course, I know Wink
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





PostPosted: Tue Dec 13, 2005 6:09 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote

[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





PostPosted: Tue Dec 13, 2005 6:13 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote

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





PostPosted: Tue Dec 13, 2005 6:34 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote

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





PostPosted: Tue Dec 13, 2005 10:19 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote

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





PostPosted: Wed Dec 14, 2005 12:53 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote


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





PostPosted: Wed Dec 14, 2005 3:45 pm    Post subject: Re: Prevent calling operator-> as function Reply with quote


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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.