-1

I need to make class B to work with graph of related objects of class A. An instance of B contains A by value, and links to linked B objects(array indexes). Array of B must to be private as OOP principles dictate. I have long generated initialization list.

//What I want to do(not working)
header:
class A{};

class B{
    static const B array[24]={B(A(),0,0,0,0,0,0),//zeros are numbers
                            ...............//many rows
                            B(A(),0,0,0,0,0,0)};
    A a;
    char l[6];
public:
    B(A _a,char l1, char l2, char l3,char l4, char l5, char l6);
};
//attempt with initialization in cpp
header:
class A{};

class B{
    static const extern B array[24];
    A a;
    char l[6];
public:
    B(A _a,char l1, char l2, char l3,char l4, char l5, char l6);
};

cpp:
static const B::array={B(A(),0,0,0,0,0,0),//zeros are numbers
                       ...............//many rows
                       B(A(),0,0,0,0,0,0)};

I tried above and similar variants. Compiler says I can't use conflicting specifiers or incomplete types or that field was private. In the past instead of class I used namespace and it worked, but that way array is not encapsulated.

//global variable in namespace(works, but not private)
header:
class A{};

namespace NSB{
class B{
    A a;
    char l[6];
public:
    B(A _a,char l1, char l2, char l3,char l4, char l5, char l6);
};
const extern B array[24];
}

cpp:
const NSB array[24]={B(A(),0,0,0,0,0,0),//zeros are numbers
                    ...............//many rows
                    B(A(),0,0,0,0,0,0)};
}

I expect a way to make preinitialized private static array somehow.

2 Answers2

1

Unsure what you tried differently ... that seems to compile (and run):

class A{};

class B{
    static const B array[2];
    A a;
    char l[6];
public:
    B(A _a,char l1, char l2, char l3,char l4, char l5, char l6) {}
};

const B B::array[2]={B(A(),0,0,0,0,0,0), B(A(),0,0,0,0,0,0)};

int main() {} 
Öö Tiib
  • 10,809
  • 25
  • 44
  • What happens in: "const B B::array[2]={B(A(),0,0,0,0,0,0), B(A(),0,0,0,0,0,0)};"? Declaration of global const variable and suddenly initialization? – TomatOgorodow Aug 20 '23 at 17:39
  • There happens initializing of private static member of class named "B" named "array". – Öö Tiib Aug 20 '23 at 17:44
  • This works! I didn't know about that syntax and don't know why it should work like that. What terms should I search to study this area of c++? – TomatOgorodow Aug 20 '23 at 17:49
  • @TomatOgorodow Also note that if you use a braced init-list you don't have to repeat `B` in all lines. [example](https://godbolt.org/z/aWxGKqPK8) – Ted Lyngmo Aug 20 '23 at 17:50
  • Read about static members. Cppreference has usually up to date info about most things in C++ – Öö Tiib Aug 20 '23 at 17:53
0

The whole initialization can be moved to compile time using constexpr like this :

#include <array>
#include <iostream>

namespace your_namespace
{
    class A {};

    class B
    {
        A a;
        std::array<char, 6> l;

    public:
        // constexpr constructor for initialization
        // allows setup of B at compile time
        constexpr B(A&& _a, std::array<char, 6>&& values) :
            a{ _a },
            l{ values }
        {
        }

        constexpr const auto& values() const noexcept
        {
            return l;
        }
    };

    namespace details // named namespace for test, you can make it unnamed to hide it.
    {
        // the array of instances of B 
        // can be a compile time resource (no need to use static initialization)
        static constexpr std::array<B, 2> b_array
        { {
            {A{},{0,0,0,0,0,0}}, // constructor parameters for a B instance, the values are an array and need their own {}
            {A{},{1,1,1,1,1,1}}
        } };

        // this b_array cannot be a static constexpr member of B because
        // B must be a complete type first.
    }

} // namespace your_namespace

int main()
{
    for (const auto& b : your_namespace::details::b_array)
    {
        for (const auto& value : b.values())
        {
            std::cout << static_cast<int>(value) << " ";
        }
        std::cout << "\n";
    }

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19