Search code examples
c++multidimensional-arraystaticdynamic-arraysmember-variables

First Dimension Unsized Class Member


I have a class I'm converting:

class MyClass
{
public::
    void foo( void )
    {
        static const char* bar[][3] = { NULL };
        func( bar );
    }
};

Now I want to make bar a member variable, but because the first dimension is unsized I can't. I also can't pass const char** bar[3] to void func( const char* param[][3] ). Is there a workaround for this that I'm unaware of, or is this a situation where I must use a method static?

Edit in Response to Jarod42

Matching the initialization of bar is my problem here. I think I should at least be able to accomplish this in the ctor body, if not the ctor initialization list. Here's some test code:

static const char* global[][3] = { NULL };

void isLocal( const char* test[][3] )
{
    // This method outputs" cool\ncool\nuncool\n
    if( test == NULL )
    {
        cout << "uncool" << endl;
    }
    else if( *test[0] == NULL )
    {
        cout << "cool" << endl;
    }
}

class parent
{
public:
    virtual void foo( void ) = 0;
};

parent* babyMaker( void )
{
    class child : public parent
    {
    public:
        virtual void foo( void )
        {
            static const char* local[][3] = { NULL };

            isLocal( local );
            isLocal( global );
            isLocal( national );
        }
        child():national( nullptr ){}
    private:
        const char* (*national)[3];
    };
    return new child;
}

int main( void )
{
    parent* first = babyMaker();
    first->foo();
}

Solution

  • const char* bar[][3] is not const char** bar[3] but const char* (*bar)[3].
    So you may want something like:

    class MyClass
    {
    public:
        MyClass() : bar(nullptr) {}
    
        void foo() { func(bar); }
    private:
        const char* (*bar)[3];
    };
    

    I suggest to use typedef as:

    class MyClass
    {
    public:
        typedef const char* bar_t[3];
    public:
        MyClass() : bar(new bar_t[2]) {
            for (int j = 0; j != 2; ++j) {
                for (int i = 0; i != 3; ++i) {
                    bar[j][i] = nullptr;
                }
            }
        }
        ~MyClass() { delete [] bar; }
    
        void foo() { func(bar); }
    
    private:
        MyClass(const MyClass&); // rule of three
        MyClass& operator =(const MyClass&); // rule of three
    private:
        bar_t* bar;
    };
    

    or:

    class MyClass
    {
    public:
        typedef const char* bar_t[3];
    public:
        MyClass() { for (int i = 0; i != 3; ++i) { bar[0][i] = nullptr; } }
    
        void foo() { func(bar); }
    
    private:
        bar_t bar[1];
    };