代码之家  ›  专栏  ›  技术社区  ›  macroland

向量中特定位置的唯一_ptr向量

  •  -1
  • macroland  · 技术社区  · 8 年前

    我有一个叫做Grid的类,它由单元格组成。每个单元格都可以有自己的格式(该概念类似于MS Excel)。

    网格中的格式保存在向量中 std::vector<std::unique_ptr<CellFormat>> m_CellFormatTable

    由于网格是一个矩阵,当单元格格式发生变化时,每个单元格都属于矩阵的不同部分,因此应反映在矩阵的正确部分,即在向量中正确定位(CellFormatTable)。因此,在这个阶段,我不能使用 push_back 向量的方法。

    CellFormat类:

    struct CellFormat
    {
        wxFont m_Font;
        wxColor m_BackgroundColor, m_TextColor;
        int m_HorizontalAlignment, m_VerticalAlignment;
    
        CellFormat(Grid* ws) {
            m_BackgroundColor = ws->GetDefaultCellBackgroundColour();
            m_TextColor=ws->GetDefaultCellTextColour();
            int horizontal = 0, vertical = 0;
            ws->GetDefaultCellAlignment(&horizontal, &vertical);
        }
    
        CellFormat(const CellFormat& other) {
            m_Font = other.m_Font;
            m_BackgroundColor = other.m_BackgroundColor;
            m_TextColor = other.m_TextColor;
            m_HorizontalAlignment = other.m_HorizontalAlignment;
            m_VerticalAlignment = other.m_VerticalAlignment;
        }
    
        CellFormat& operator=(const CellFormat& other) {
            if (this == &other) return *this;
            m_Font = other.m_Font;
            m_BackgroundColor = other.m_BackgroundColor;
            m_TextColor = other.m_TextColor;
            m_HorizontalAlignment = other.m_HorizontalAlignment;
            m_VerticalAlignment = other.m_VerticalAlignment;
    
            return *this;
        }
    };
    

    在网格中。h

    class Grid{
        std::vector<std::unique_ptr<CellFormat>> m_CellFormatTable;
        //
        CellFormat* GetCellFormat(int row, int column);
        void SetCellFormat(int row, int column, CellFormat format);
        void ApplyCellFormat(int row, int column, const CellFormat* format);
        CellFormat* CreateCellFormat(int row, int column);
        //rest is omitted
    }
    

    In Grid.cpp

    Grid(some arguments){
        m_CellFormatTable.resize(nrows*ncols);
        //rest is omitted
    }
    
    CellFormat* Grid::GetCellFormat(int row, int column)
    {
        int ncols= GetNumberCols();
    
        return m_CellFormatTable[row*ncols+ column].get();
    }
    
    void Grid::SetCellFormat(int row, int column, CellFormat other)
    {
        CellFormat* format = GetCellFormat(row, column);
        if (format == 0) format = CreateCellFormat(row, column);
        *format = other;
    }
    
    void Grid::ApplyCellFormat(int row, int column, const CellFormat * format)
    {
        if (format == 0) {
            int ncols= GetNumberCols();
            //Set everything to default values
            //Omitted
    
            m_CellFormatTable[row*ncols+ column].reset();
        }
        else {
            wxColor bgcolor = format->m_BackgroundColor;
            if (bgcolor.IsOk()) SetCellBackgroundColour(row, column, bgcolor);
            SetCellTextColour(row, column, format->m_TextColor);
            SetCellFont(row, column, format->m_Font);
            SetCellAlignment(row, column, format->m_HorizontalAlignment, format->m_VerticalAlignment);
        }
    }
    
    CellFormat* Grid::CreateCellFormat(int row, int column)
    {
        int ncols= GetNumberCols();
        CellFormat* format = new CellFormat(this);
        m_CellFormatTable.emplace(m_CellFormatTable.begin() + row*ncols+ column, std::move(format));
    
        return format;
    }
    

    CellFormat* format = ws->GetCellFormat(row, col);
    if (format == 0) format = ws->CreateCellFormat(row, col);
    
    if (ChangeFillColor) {
        ws->SetCellBackgroundColour(row, col, m_LastChosenFillColor);
        format->m_BackgroundColor = m_LastChosenFillColor;
    }
    

    ApplyCellFormat 在点处的函数 format->m_BackgroundColor 因为应该是单元格背景色的颜色无效。这告诉我 CreateCellFormat 未将CellFormat放置在正确的位置。我尝试使用 insert emplace 但编译器(VS 2015)抱怨了我所有的尝试。

    欢迎提出任何想法。

    4 回复  |  直到 8 年前
        1
  •  1
  •   Ripi2 user10587824    8 年前


    一是你添加了一个 CellFormat* 但是你的向量存储 unique_ptr std::make_unique 使用新格式。

    0 如果它们尚未设置。这是错误的。向量只有“推”或“安放”的元素数。
    vector[51] 未定义( vector.at(51)
    首先添加所有单元格格式,一些值为0表示尚未设置。或者重新思考你的战略。

    顺便说一句,你可以用 wxGridCellAttr

        2
  •  1
  •   Walter    8 年前

    从你使用 vector 属于 unique_ptr std::map (或 std::unordered_map 如果矩阵非常大)的对象(不是 唯一ptr

    template<typename T>
    struct grid
    {
        using index = std::pair<unsigned, unsigned>;
    
        // insert element if not already present
        // returns if insertion occurred
        template<typename...Args>
        bool insert(index const&i, Args&&...args)
        {
            return data.emplace(std::forward<Args>(args)...).second;
        }
    
        // remove element (if it exists)
        void remove(index const&i)
        {
            data.erase(i);
        }
    
        // get pointer to element, may be nullptr
        T* get(index const&i)
        {
            auto it = data.find(i);
            return it==data.end() ?
                nullptr : std::addressof(*it);
        }
      private:
        std::map<index,T> data;
    };
    
        3
  •  0
  •   Francis Cugler    8 年前

    我在代码的这一部分看到您的代码失败的原因:

    CellFormat* format = ws->GetCellFormat(row, col);
    if (format == 0) format = ws->CreateCellFormat(row, col);
    
    if (ChangeFillColor) {
        ws->SetCellBackgroundColour(row, col, m_LastChosenFillColor);
        format->m_BackgroundColor = m_LastChosenFillColor;
    }
    

    取决于类的定义:

    class Grid{
        std::vector<std::unique_ptr<CellFormat>> m_CellFormatTable;
        //
        CellFormat* GetCellFormat(int row, int column);
        void SetCellFormat(int row, int column, CellFormat format);
        void ApplyCellFormat(int row, int column, const CellFormat* format);
        CellFormat* CreateCellFormat(int row, int column);
        //rest is omitted
    }
    

    默认情况下,类的成员和函数设置为 private:

    将课堂改为:

    class Grid {
    public:
        typedef std::vector<std::unique_ptr<CellFormat>> Format;
    private:
        Format m_CellFormatTable;
    
    public:
        CellFormat* getCellFormat( int row, int column );
        void        setCellFormat( int row, int column, const CellFormat& format );
        void        applyCellFormat( int row, int column, const CellFormat& format );
    
       // Add This Function If Needed
       Format getCellFormatTable() const { return m_CellFormatTable; }
    };
    

    public: 然后外部和非友元对象现在可以访问此类的成员函数,并能够通过get方法返回数据结构。

        4
  •  0
  •   macroland    8 年前

    谢谢大家的宝贵意见和帖子。最后,它按预期工作。

    正如Ripi2所建议的那样, CellFormat

    虽然遍历网格的所有行和列并创建默认格式不是最好的主意,但Walter的建议将是我未来的工作,即使用集合。

    Grid(some arguments){
        for (int i = 0; i < nrows*ncols; i++) {
            m_CellFormatTable.emplace_back(new CellFormat(this));
        }
       //Rest is omitted
    }
    

    CellFormat* Grid::CreateCellFormat(int row, int column)
    {
        int ncols = GetNumberCols();
        CellFormat* format = new CellFormat(this);
        std::unique_ptr<CellFormat> ptr(format);
        m_CellFormatTable.emplace(m_CellFormatTable.begin() + row*ncols + column,std::move(ptr));
    
        return format;
    }
    

    跟踪格式的一种方法是:

    CellFormat* format = ws->GetCellFormat(i, j);
    if (ChangeFillColor) {
        ws->SetCellBackgroundColour(i, j, m_LastChosenFillColor);
        format->m_BackgroundColor = m_LastChosenFillColor;
    }