|
|
In article <3d9d7fdf@news.povray.org>, Warp <war### [at] tagpovrayorg>
wrote:
> I have sometimes wished this too. It would certainly be useful if you
> could say "class A can access this private method of this class B, but
> nothing else".
It would be helpful in something similar to the MVC pattern. You could
have classes that implement the objects but are not concerned with
drawing them, and classes that have access to certain APIs that let them
draw the objects, without exposing these APIs to everything else. Good
for tightly related classes that don't have strong dependencies on each
other. You could write OpenGL and DirectX versions of the viewer classes
without ever touching or recompiling the model classes, just derive them
from a class that has access. Hmm...this brings up the question of
whether access should be inherited or not. I think it would make sense
if it was.
> class B
> {
> private:
> void foo() friend A;
> };
>
> (If you want more than one class to have access to the method, you could
> just list them separated with commas after the 'friend' keyword.)
I'm not sure I like that...I think it muddles the meaning of "friend".
Maybe something like this, which seems to fit in with the other access
labels:
class MyClass {
exposeto SomeClass:
...declarations exposed to SomeClass...
exposeto AnotherClass:
...declarations exposed to AnotherClass...
exposeto SomeClass, AnotherClass:
...declarations exposed to SomeClass and AnotherClass...
public:
...declarations exposed to all external code...
};
Maybe something like this too:
class MyClass {
interface GeneralAPI access public {
...drawing API declarations...
};
interface DrawingAPI access Viewer {
...drawing API declarations...
};
};
The first one has no functionality over a simple "public:" label, but
helps document the code as having these functions be grouped together.
The second one is similar, but only a specific list of classes has
access to the API.
> I don't use it often, but sometimes it's handy. For example:
> cout << "The switch 1 is " << (switch1 ? "on" : "off") << endl;
I would have to agree here...I've just never had to do that. I probably
won't add this function to CSDL, though I might add a select() function.
It could be done now:
function select(cond, ifTrue, ifFalse) {
if(cond)
return ifTrue;
else
return ifFalse;
};
Or eventually something like this, to handle any number of possiblities:
function select(cond) {return params[cond + 1];};
console.write("The switch 1 is ", select(switch1, "on", "off"), "\n");
Hmm...longer by a few characters, and maybe no more readable, but a C++
version:
template<typename T>
inline T select(bool cond, T ifTrue, T ifFalse)
{
if(cond)
return ifTrue;
else
return ifFalse;
}
cout << "The switch 1 is " << select(switch1, "on", "off") << endl;
Would it work? I always mess up on templates. It isn't quite the same as
the Sapphire version, because the parameters and return value aren't
passed by reference. "select(foo, a, b).SetSomething()" wouldn't work,
because it would be calling SetSomething() on a copy. However, if
references are used, 'select(switch1, "on", "off")" wouldn't work
because the parameters are temporaries...pointers will work fine though:
select(foo, &a, &b)->SetSomething()
Should work.
Or:
char * modes[2] = {"off", "on"};//rewrite to use string class if you want
cout << "The switch 1 is " << modes[switch1] << endl;
The Sapphire equivalent (still working out the syntax):
def modes: ["off", "on"];
console.write("The switch 1 is ", modes[switch1], "\n");
Has the advantage of being easy to expand to more than 2 possiblities.
--
Christopher James Huff <cja### [at] earthlinknet>
http://home.earthlink.net/~cjameshuff/
POV-Ray TAG: chr### [at] tagpovrayorg
http://tag.povray.org/
Post a reply to this message
|
|