0

For reasons (mostly around the idea of mock-ability), we have this abstract interface idea...

struct BundleOfInterfaces
{
   static Interface1& interface1;
   static Interface2& interface2;
   ...
};  

So we access the functions in the interfaces via BundleOfInterfaces::interface1.function1(...)

How can I make the references immutable so nobody can do BundleOfInterfaces::interface1 = MyNewInterface1;?

Placing const on it seems to make the reference to a const object, which forces the referenced implementations to have all their methods be const (and prevents internal states).

I know I can hide it behind a getter function and make the actual reference private, but I assume there's some way I can do this with const, but it doesn't seem to matter where the const gets placed.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
Russ Schultz
  • 2,545
  • 20
  • 22
  • 5
    The reference is already immutable. `InterfacesBundle::interface1 = MyNewInterface1;` does not change the reference. It changes the value of the thing the reference refers to. If you don't want the thing being refered to to be changed, then that needs to be `const`. – NathanOliver May 02 '23 at 13:37
  • 1
    or `Interface1::operator=() = delete;` but that still is not an issue of the reference but of the interface – 463035818_is_not_an_ai May 02 '23 at 13:47
  • Ah, thanks all, especially @NathanOliver. The test code I wrote was allowing the assignment to compile, but I didn't actually test to see if it changed which interface was being referenced. – Russ Schultz May 02 '23 at 13:57
  • @463035818_is_not_a_number also thanks for your comment. Adding the deleted assignment operator prevents the assignment from compiling, preemptively dealing with the potential confusion. – Russ Schultz May 02 '23 at 13:59
  • References cannot be "retargeted" to refer to another object. You can use a pointer if you want to change where it points: `static Interface1 *const interface1;` Writing `const` _after_ the `*` means that the pointer is const, but the actual `Interface1` is not. – Thomas May 02 '23 at 14:16
  • @anatolyg While I appreciate the effort to add duplicates, I don't believe any of the "duplicate" questions actually directly answer the question I have asked. – Russ Schultz May 02 '23 at 15:01
  • I don't think this question should be marked as duplicate, but this is not too important, since you got a good answer. Voted to reopen just because I can. – anatolyg May 02 '23 at 15:09
  • @anatolyg sorry, I thought you were the editor that added that. :) I'm good and learned something today. – Russ Schultz May 02 '23 at 15:22

1 Answers1

3

Just wrapping up what has been said in comments...

The reference is already immutable. You cannot rebind a reference. Memory usage to store the static member aside, the simple image of a reference merely being an alias for the referenced object is appropriate here. You can assign to the reference because you can assign to an instance of Interface1. The only way to prevent BundleOfInterfaces::interface1 = MyNewInterface1; is to prevent assignment to an instance of Interface1 in general. This is not actually related to using a reference as static member and can be achieved by deleting the assignment Interface1::operator=(const Interface1&) = delete;.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185