friend class
Hey I didn't even need to do that forward declaration thing. All I had to do was say:
friend struct Gizmo;
in the Bomb struct and the compiler didn't care that Gizmo wasn't declared or defined or anything.
friend struct Gizmo;
in the Bomb struct and the compiler didn't care that Gizmo wasn't declared or defined or anything.
It should be noted that resorting to "friend" is really a last-ditch effort sort of thing. Its there for when it makes sense, but the brief description you gave, perhaps because it was lacking in details, doesn't convince me that you're calling in "friend" out of necessity, rather than convenience.
It works, its fine, its not something you have to revisit now if you don't want. I'm just saying that "friend" is the strongest relationship you can express in C++, even stronger than inheritance, and as such, should be wielded wisely. Its a very powerful, and sometimes necessary, tool to be sure, but good engineering practice is to use the "weakest" tool that does the job adequately, because they have fewer negative side effects.
It works, its fine, its not something you have to revisit now if you don't want. I'm just saying that "friend" is the strongest relationship you can express in C++, even stronger than inheritance, and as such, should be wielded wisely. Its a very powerful, and sometimes necessary, tool to be sure, but good engineering practice is to use the "weakest" tool that does the job adequately, because they have fewer negative side effects.
I don't know, Ravyne. I use friend for Nodes in linked lists. I make everything in the Node private and make functions that can return values to everything. And then I make the Node a friend of the container. I think that makes sense.
And the Bomb above. ...well I guess I'd have to post a few pages of code to show what I'm doing. Not worth it. But Bomb is just a little struct. And basically I want nothing to be able to modify the contents of Bombs. Except Gizmos, which I want to be able to modify Bombs however they please. I think what I'm doing makes sense.
And the Bomb above. ...well I guess I'd have to post a few pages of code to show what I'm doing. Not worth it. But Bomb is just a little struct. And basically I want nothing to be able to modify the contents of Bombs. Except Gizmos, which I want to be able to modify Bombs however they please. I think what I'm doing makes sense.
Quote:Original post by icecubeflower
Hey I didn't even need to do that forward declaration thing. All I had to do was say:
friend struct Gizmo;
in the Bomb struct and the compiler didn't care that Gizmo wasn't declared or defined or anything.
The statement "friend struct Gizmo;" is both a forward declaration of the class and a declaration of friendship. :)
Quote:Original post by icecubeflower
I don't know, Ravyne. I use friend for Nodes in linked lists. I make everything in the Node private and make functions that can return values to everything. And then I make the Node a friend of the container. I think that makes sense.
I may sound harsh on this but I my opinion whenever you use "friend" in your code you have build a design flaw into your code. Sure, there are some cases where it might be ok to use a friend but if you think you stumble across such a case you have to think twice and then rethink twice why you need this friend and how you can solve your actual problem by design rather than hacking an object access rules.
Basically a class is an object that has an interface. By public, protected, and private you defined who has access to which parts of the object's interface to mess with the object's internal states.
So far so good. But by using friend you actually allow another class to do whatever it wants with the object since it can not only access the whole interface but also change member attributes directly. That is not what object oriented programming was meant to be.
If you have a node class it should provide a public interface (a couple a methods) to let another class manage instances of the node class. The linked list should then be a class that can manage instances of a certain class type (or it could even be a template class) using the public interface of the class it does link together.
The node class must provide all public methods that are required for a manager class to deal with nodes. If you need to declare a friend as manager so that this manager can mess with the node's state you are constructing a weakness and a probable source of errors into your code. If you cannot implement the linked list class without being a friend of your node class than it is most likely that you node class' public interface lacks functionality it should provide when we are talking about object oriented programming.
Of course this is only my point of view, so no offense meant. But I always try to evangelize what I believe to be best practices of object oriented programming [grin]
Quote:
I don't know, Ravyne. I use friend for Nodes in linked lists. I make everything in the Node private and make functions that can return values to everything. And then I make the Node a friend of the container. I think that makes sense.
You could do that, but if you look at something like std::list, you'd notice that having a Node would be simply completely useless for anything but std::list. std::list itself never exposes a Node to the user, so even if you could create and manipulate Node instances on your own and in any way you like, it would not affect any std::list.
E.g, this is from the GCC's std::list implementation.
namespace _GLIBCXX_STD{ /// @if maint Common part of a node in the %list. @endif struct _List_node_base { _List_node_base* _M_next; ///< Self-explanatory _List_node_base* _M_prev; ///< Self-explanatory static void swap(_List_node_base& __x, _List_node_base& __y); void transfer(_List_node_base * const __first, _List_node_base * const __last); ... }; /// @if maint An actual node in the %list. @endif template<typename _Tp> struct _List_node : public _List_node_base { _Tp _M_data; ///< User's data. };
Notice that it's all public. The things that should keep you away from it are identifiers beginning with underscore, the compiler-specific namespace - and the fact that these structs have no use for you.
I don't care if people are harsh, I'll take all the info I can get.
Now that I think about it putting private member variables in a Node was pretty pointless. I mean I have a container class with a linked list of Nodes. Somewhere a container class is declared and you can only use the public functions of the container class. It doesn't matter if the Node is all public, the container class is the only thing that can get at it anyway. Because its *head and *tail and everything are private. (visitor just said the same thing I think, he posted while I was writing or maybe I didn't look at the 2nd page or something)
Now that I think about it putting private member variables in a Node was pretty pointless. I mean I have a container class with a linked list of Nodes. Somewhere a container class is declared and you can only use the public functions of the container class. It doesn't matter if the Node is all public, the container class is the only thing that can get at it anyway. Because its *head and *tail and everything are private. (visitor just said the same thing I think, he posted while I was writing or maybe I didn't look at the 2nd page or something)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement