簡體   English   中英

在 C++ 中實現二維數組模板的問題

[英]Problems with implementing 2D array template in C++

我嘗試為通用二維數組創建一個模板,這將允許我創建不同數據類型的 arrays 並用隨機值填充它們。 我當前的代碼看似創建了三個對象,但是用相同的隨機值填充它們,而 double 類型的 mass 甚至沒有 double 值。 我認為問題出在構造函數和指針的某個地方,但我不確定如何解決這個問題。

我的 class:

template <typename T>
    class MATRIX
    {
    private:
      T** M;
      int m = 8;
      int n = 12;
    public:
    MATRIX(T matr[8][12]);
      void fill();
      };

構造函數:

template <typename T>
 MATRIX<T>::MATRIX(T matr[8][12]){
    M = (T**) new T*[m];
    for (int i = 0; i < m; i++)
      M[i] = (T*)new T[n];
}

方法:

    template <typename T>
    void MATRIX<T>::fill(){
        T randomNumber;
        srand((unsigned) time(0));
        for (int i = 0; i < m; i++){
          for (int j = 0; j < n; j++){
            randomNumber = (rand() % (122 + 1 - 65)) + 65;
            M[i][j] = randomNumber;} } }

主要的:

 int main() {
    int intMatr[8][12];
    MATRIX<int>a(intMatr);
    a.fill();
    
    double doubleMatr[8][12];
    MATRIX<double>b(doubleMatr);
    b.fill();
    
    char charMatr[8][12];
    MATRIX<char>c(charMatr);
    c.fill();
    return 0; }

並不是對您的問題的直接回答,但是,如果您不需要,請盡量不要使用 new/delete,如本示例所示(請注意,array2d_t class 是我之前編寫的並在此示例中重復使用,因此它可以執行比需要多一點)我還展示了如何使用 c++ 的隨機生成器為您的矩陣創建字符。

#pragma once

#include <vector>
#include <iostream>
#include <random>
#include <utility>
#include <string>
#include <stdexcept>

//---------------------------------------------------------------------------------------------------------------------

template<typename type_t, std::size_t rows_v, std::size_t cols_v>
struct array2d_t 
{
    constexpr array2d_t() :
        m_values{}
    {
    }

    constexpr explicit array2d_t(const type_t(&values)[rows_v][cols_v])
    {
        // constexpr compatible initialization
        for (auto row = 0; row < rows_v; ++row)
        {
            for (auto col = 0; col < cols_v; ++col)
            {
                m_values[row][col] = values[row][col];
            }
        }
    }

    ~array2d_t() = default;

    // return a row
    constexpr auto operator[](const std::size_t row)
    {
        //assert(row < rows_v);
        if (row >= rows_v) throw std::invalid_argument("row out of bounds");
        return row_t(&m_values[row][0]);
    }

    // return a const row
    constexpr auto operator[](const std::size_t row) const
    {
        //assert(row < rows_v);
        if (row >= rows_v) throw std::invalid_argument("row out of bounds");
        return const_row_t(&m_values[row][0]);
    }

    // return iterator to the first row (so array can be used in range based for loop)
    constexpr auto begin() 
    {
        return std::begin(m_values);
    }

    // return iterator to the last row (so array can be used in range based for loop)
    constexpr auto end() 
    {
        return std::end(m_values);
    }

    constexpr std::size_t rows() const 
    {
        return rows_v;
    }

    constexpr std::size_t columns() const
    {
        return cols_v;
    }

private:
    //-----------------------------------------------------------------------------------------------------------------
    ///  row helper
    struct row_t
    {
        constexpr row_t(type_t* row) :
            m_row{ row }
        {
        }

        constexpr type_t& operator[](const std::size_t column) const
        {
            //assert(column < cols_v);
            if (column >= cols_v) throw std::invalid_argument("column out of bounds");
            return m_row[column];
        }

        constexpr auto begin() const
        {
            return std::begin(m_row);
        }

        constexpr auto end() const
        {
            return begin() + rows_v;
        }

    private:
        type_t* m_row;
    };

    //-----------------------------------------------------------------------------------------------------------------
    // row helper for const 
    struct const_row_t
    {
        constexpr const_row_t(const type_t* row) :
            m_row{ row }
        {
        }

        constexpr const type_t& operator[](const std::size_t column) const
        {
            //assert(column < cols_v);
            if (column >= cols_v) throw std::invalid_argument("column out of bounds");
            return m_row[column];
        }

        constexpr auto begin() const
        {
            return std::begin(m_row);
        }

        constexpr auto end() const
        {
            return begin() + rows_v;
        }

    private:
        const type_t* m_row;
    };

    type_t m_values[rows_v][cols_v];
};

template<typename type_t, std::size_t rows_v, std::size_t cols_v>
std::ostream& operator<<(std::ostream& os, array2d_t<type_t,rows_v,cols_v>& arr)
{
    for (const auto& row : arr)
    {
        bool comma = false;

        for (const auto& value : row)
        {
            if (comma) std::cout << ", ";
            std::cout << value;
            comma = true;
        }

        std::cout << "\n";
    }

    std::cout << "\n";

    return os;
}

//---------------------------------------------------------------------------------------------------------------------

class MATRIX :
    public array2d_t<char, 8, 12>
{
public:

    void fill()
    {
        // initialize a vector of valid character for random to pick from
        // static ensures this is only done on first call to function
        static std::vector<char> valid_chars = []
        {
            std::vector<char> chars;
            chars.reserve(52);
            for (char c = 'A'; c < 'Z'; ++c) chars.push_back(c);
            for (char c = 'a'; c < 'z'; ++c) chars.push_back(c);
            return chars;
        }();

        // this is how to setup random number generation in C++
        static std::random_device rd{};
        static std::default_random_engine random{ rd() };
        static std::uniform_int_distribution<std::size_t> distribution(0, valid_chars.size() - 1);

        for (auto& row : *this)
        {
            for (auto& value : row)
            {
                value = valid_chars[distribution(random)];
            }
        }
    }
};

//---------------------------------------------------------------------------------------------------------------------

int main()
{
    MATRIX m;
    m.fill();

    std::cout << m;
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM