-1

As the question states, if the call is queue1.compareQueues(queue2), is it ok to access queue2.frontNode within the queue1's method?

bool Queue::compareQueues(Queue& queue2) {
    Node* queue1Pointer = frontNode;
    Node* queue2Pointer = queue2.frontNode;
    return true;
};
  • 4
    Yes that's prefectly fine and normal. This is unrelated but your method and parameter should be `const` however, `bool Queue::compareQueues(const Queue& queue2) const {` – john Jan 20 '21 at 16:11
  • Yes. a class has access to `private` members in _all_ instances, not just the current one as pointed-to by `this`. Whether it is good design or not is a different question... which is not clear from the no-op code you have shown here. – underscore_d Jan 20 '21 at 16:19
  • @john May I know why it should be const and what do you mean by `const{`? – HotPotTofu Jan 20 '21 at 16:23
  • @underscore_d Your answer is very informative, could you roughly explain or give an example of when it is correct to do this and when it is not? (e.g. when it is considered good design or bad design) – HotPotTofu Jan 20 '21 at 16:25
  • @HotPotTofu Not really. I don't have concrete examples. It might be fine most of the time. I suspect however that sometimes it can be bad design, but I don't know if that's the case for you, because the code you've shown doesn't make it clear what you're trying to achieve and hence whether it's a good approach. I just mentioned that to emphasise that 'is it valid to compile' vs 'is it a good idea' can have different answers in some situations :-) – underscore_d Jan 20 '21 at 16:31
  • 1
    @HotPotTofu In the normal way of things a function to compare two queues would not modify either of the two queues, therefore in this function both queues should be const. `const {` makes `this` const. – john Jan 20 '21 at 16:31
  • 1
    @HotPotTofu Personally I would (almost) never consider this to be bad design. The language allows it for good reason. If you allow the outside world access to class privates then it can break the class invariants but code that is part of the class should be trusted not to do this. Similarly code outside the class should not depend on class internals, but for code inside the class this is not a problem. – john Jan 20 '21 at 16:32
  • @john Thank you for your prompt reply. I have 2 questions 1) `bool Queue::compareQueues(const Queue& queue2) const {` does it mean that the second const is after the parameter and before the function body declaration? As I have never seen const in this location before and can only guess that `) const {` refers to the queue1 that called the function. 2) Is it correct to say that the & sign in `Queue& queue2` is needed to prevent the program from calling the deconstructor for queue2 after the function has ended? As I found that without the &, my queue is being deconstructed twice – HotPotTofu Jan 20 '21 at 16:40
  • The deconstruction twice refers to the queue being deconstructed once after the function ended and second time after the main program ended (return 0). This led to the program throwing an error when the main program tried to deconstruct the queue. – HotPotTofu Jan 20 '21 at 16:44
  • @HotPotTofu Big questions, and only a small space for comment. 1) In this position `) const {` const refers to the `this` pointer. Normally the `this` pointer is type `Queue*`, but with the extra const it is `const Queue*`. and yes in effect it ensures the queue which called the function will not be modified by the function. – john Jan 20 '21 at 16:47
  • 2) `&` means a reference. what gets passed to the function is a reference to the queue not a copy of the queue. Your observation about the destructor is correct, when a queue is copied a new queue object is created, and that new queue object will also be destroyed. So the full answer is that using `&` avoids a copy which in turn avoids the copy being destroyed. Further very important reading can be found [here](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – john Jan 20 '21 at 16:51
  • The error you found is undoubtedly because your queue class is not following the rule of three as described in the link in the previous comment. As such your queue class is currently bugged because you cannot safely make copies of queue objects, – john Jan 20 '21 at 16:53
  • @john Thank you. I needed that. Was wondering why the error without &. As without &, it is a copy and the copy being destroyed should be ok as the main will destroy the original. However, it seems that the copy in the function, is not actually a copy! And the function attempting to deconstruct the copy when it ends actually deconstructs the original. The return 0 in main then deconstructs the original which causes the error. I still do not get why the function deconstructing the copy ends up actually deconstructing the original other than because it is a pointer-based implementation. – HotPotTofu Jan 20 '21 at 16:55
  • 1
    @HotPotTofu It will be because you have not written a copy constructor for your class (or that you have written one but it is bugged). As before see the link, it's a very important topic that is reasonably well explained there (or in any half decent C++ book). – john Jan 20 '21 at 16:56

1 Answers1

1

Member access is not per instance but per class. Within the class definition you have access to all private members (of any instance of that class).

From cppreference:

The name of every class member (static, non-static, function, type, etc) has an associated "member access". When a name of the member is used anywhere a program, its access is checked, and if it does not satisfy the access rules, the program does not compile: [...]

This is just the "Explanation" (examples follow thereafter), but note that it says "name of every class member", not "members of objects".

Sloppy speaking, the reasoning of having access per class is that inside a member method you should know what you are doing when touching the internals. Wether you are touching the internals of this or of some other does not change the fact that you need to be aware of the inner workings of the type.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    A note: On a practical level "Member Access on class level" is a logical choice for the language. An objects methods are already tightly bound to the state of the class (i.e. your methods have to know how the class works already). So having cross instance accesses to members is safe. – Martin York Jan 20 '21 at 17:18
  • @MartinYork I was considering to add something like that while writing. I added it now, maybe it reflects what you are saying. – 463035818_is_not_an_ai Jan 20 '21 at 17:23
  • `inside a member method you should know` Roughlt translates to `members are "Tightly coupled" with the state of the object"` or `Tightly bound`. – Martin York Jan 20 '21 at 17:26