首页 > 解决方案 > How can I get a method to return a pointer to a const array

问题描述

Consider the following code.

class SomeClass{};

class AnotherClass
{
public:
    SomeClass c1;
    SomeClass c2;
    SomeClass c3;
    const SomeClass* someClassArray[3] = { &c1, &c2, &c3 };
    
    const SomeClass** GetSomeClassArray () 
    {
      return someClassArray;
    }
};

int main ()
{
    AnotherClass anotherClass;
    const SomeClass** someClassArray = anotherClass.GetSomeClassArray ();
    
    SomeClass* someClass2 = new SomeClass;
    someClassArray[0] = someClass2; //This should not be allowed
}

I am declaring the array someClassArray as const. I am specifying the return type of GetSomeClassArray as const SomeClass** and yet, I am still allowed to modify the contents of the array later in the main function.

I also noticed that adding const specifier to the method as such: const SomeClass** GetSomeClassArray () const causes an error.

Why is this the case?

标签: c++

解决方案


Your interpretation of what is const is wrong.

The term const binds left (unless it is on the very left then in binds right).

// so This
const SomeClass* someClassArray[3] = { &c1, &c2, &c3 };

// Equivelent to this:
SomeClass const * someClassArray[3] = { &c1, &c2, &c3 };

So now we can read the type easier. Types are read right to left.

SomeClass const * [3]
                  ^^^ Array of
                ^     Pointer To
^^^^^^^^^^^^^^^       const SomeClass

So you have an array of pointer to "const SomeClass". So the "SomeClass" object are const but the pointers are not. If you want the array to be imutable then make the pointers also const.

SomeClass const * const [3]
                        ^^^ Array of
                ^^^^^^^     const Pointer To
^^^^^^^^^^^^^^^             const SomeClass

That being said. That's probably not the best way of declaring that.

Why not just declare an array of objects?

    const SomeClass someClassArray[3];

Also a return type of ** is loosing information on the size of the array, so that is not the greatest.

     // Updated to put const in correct place first.
     SomeClass const  *const  * GetSomeClassArray() {return someClassArray;}

     // The syntax for return an array by reference is 
     // super non intuitive. I could spend 30 minutes
     // looking up the exact syntax or we can let the
     // compiler do it for you.

     auto& GetSomeClassArray() {return someClassArray;}

or

     auto const& GetSomeClassArray() {return someClassArray;}

You want to keep the type information about the size of the array as this will help in sveral ways.


Since we are using C++ you can consider using std::array rather than a C array (or std::vector potentially).

  const std::array<SomeClass, 3> someClassArray;

推荐阅读