【问题标题】:Declare Array in Class and Initialize it in Constructor在类中声明数组并在构造函数中初始化
【发布时间】:2023-12-28 04:26:02
【问题描述】:

我有以下问题:

我在头文件中有一个类,我想在其中声明一个二维数组(映射)。

那我想在Source-File(cpp)文件的Constructor中初始化它。

到目前为止,它看起来像这样:

头文件:

class TForm1 : public TForm
{
private:    ...
public:
    __fastcall TForm1(TComponent* Owner);
    int map[][];
};

源文件:

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {

map[][] = { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 2, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 2, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1 },
{ 1, 7, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 7, 1 },
{ 1, 0, 1, 0, 1, 1, 1, 3, 1, 1, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 3, 3, 3, 3, 3, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 3, 12, 3, 13, 3, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 3, 3, 14, 3, 3, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1 },
{ 1, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 1 },
{ 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 3, 1, 0, 1, 3, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 1 },
{ 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1 },
{ 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1 },
{ 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1 },
{ 1, 2, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 2, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};

}

我知道这是非常错误的,但我在互联网上找不到任何有用的解释应该如何正确完成。

感谢您的帮助

【问题讨论】:

    标签: c++ arrays initialization declaration


    【解决方案1】:

    它既不美观也不灵活。也许你应该使用抽象工厂模式来做到这一点。而且我认为您可以使用std::vector 而不是多维数组。它有很多优点,而且 STL 库有可以处理std::vector 的算法。例如:

    class IMapInitializer
    {
    public:
        virtual void InitMap(std::vector<std::vector<int>>& map) = 0;
        virtual ~IMapInitializer(){}
    };
    
    class HardcordeMapInitializer : public IMapInitializer
    {
    public:
        virtual void InitMap(std::vector<std::vector<int>>& map) override
        {
            map = {{1,2,3},{1,2,3},{1,2,3}};
        }
    };
    
    class FileMapInitializer : public IMapInitializer
    {
    public:
        virtual void InitMap(std::vector<std::vector<int>>& map) override
        {
            //Read map from file
        }
    };
    
    //...
    class TForm1 : public TForm
    {
    private:    ...
    public:
        __fastcall TForm1(TComponent* Owner, IMapInitializer& mapInitializer );
        std::vector<std::vector<int>> map;
    };
    
    //...
    __fastcall TForm1::TForm1(TComponent* Owner, IMapInitializer& mapInitializer ) : TForm(Owner) {
    
    mapInitializer.InitMap(map);
    

    借助此模式,您可以选择更好的方式来初始化地图并在开发过程中对其进行更改。

    在我的示例中,我展示了 2 个工厂(硬代码和文件输入),您可以稍后再考虑并使用其他工厂。

    【讨论】:

    • 从 C++11 开始,您可以按值返回 std::vector 而不会受到惩罚……但是,直接传递 std::vector 似乎比工厂好。
    • 感谢您的帮助 - 这对我帮助很大
    【解决方案2】:

    C++ 不允许定义具有多个不确定维度的数组;可以写int[][15] = ...,但是写int [][] = ...是不合法的。

    如果您的所有维度都是动态的,我建议使用向量向量。请参阅以下程序来说明这一点:

    class ClassWith2DArray {
    public:
        ClassWith2DArray();
        vector<vector<int>> map;
    };
    
    ClassWith2DArray::ClassWith2DArray() : map ({{2,3},{3,4}}) {}
    
    
    int main()
    {
        ClassWith2DArray c;
        for (auto row : c.map) {
            for (auto column : row) {
                cout << column << " ";
            }
            cout << endl;
        }
    
    
        return 0;
    }
    

    【讨论】:

    • 感谢您的努力 - 这很有帮助 :)