C ++ Временное решение для многомерных массивов динамического размера - PullRequest
0 голосов
/ 31 мая 2018

Я ищу легкий обходной путь для двумерных массивов динамического размера в качестве параметров, которые буквально могут использовать ученики 5-го класса.В настоящее время я пишу библиотеку для мастерской по микроконтроллерам и хочу, чтобы ее было как можно проще использовать без объяснения указателей, шаблонов и тому подобного просто потому, что сейчас не время для этого.

У меня естьследующий класс, называемый LEDBitmap, который имеет максимальную ширину 8 из-за ограничений в другой библиотеке и представляет собой битовую карту единиц и нулей для светодиодной матрицы:

Заголовочный файл:

#ifndef LEDBITMAP_H
#define LEDBITMAP_H

#include <Arduino.h>

class LEDBitmap
{

  public:
    LEDBitmap(uint8_t width, uint8_t height, uint8_t data[][8]);
    LEDBitmap(uint8_t width, uint8_t height);
    virtual ~LEDBitmap() {
      delete [] _data;
    };

  public: //methods
    uint8_t* getBitmap();
    uint8_t getPixelValue(uint8_t x, uint8_t y) {
      return _data[y][x];
    };

    void setPixelValue(uint8_t x, uint8_t y, uint8_t value) {
      _data[y][x] = value;
    };

    uint8_t getHeight() {
      return _height;
    };

    uint8_t getWidth() {
      return _width;
    };

    uint8_t getSize() {
      return _width * _height;
    };

    void clear();

  private: //members
    uint8_t _width;
    uint8_t _height;
    uint8_t _data[][8];


};

#endif

И файл cpp:

#include "LEDBitmap.h"

LEDBitmap::LEDBitmap(uint8_t width, uint8_t height) {
  _width = width;
  _height = height;
  _data = new uint8_t[width][height];
  clear();
}

LEDBitmap::LEDBitmap(uint8_t width, uint8_t height, uint8_t data[][8]) {
  _width = width;
  _height = height;
  _data = data;
}

uint8_t* LEDBitmap::getBitmap() {
  uint8_t result[_height];
  for (uint8_t h = 0; h < _height; h++) {
    uint8_t binary = 0;
    for (uint8_t w = 0; w < _width; w++) {
      binary |= _data[h][w] << (_width - w+1);
    }
    result[h] = binary;
  }
  return result;
}

void LEDBitmap::clear() {
  for (uint8_t h = 0; h < _height; h++) {
    for (uint8_t w = 0; w < _width; w++) {
      _data[h][w] = 0;
    }
  }
}

Моя проблема - первый конструктор, в котором параметр uint8_t data[][8] должен быть массивом произвольной высоты и максимальной ширины 8, но, возможно, меньше.

Я пытался использовать шаблоны, но понял, что это приведет к большим проблемам в других частях кода.Если бы я использовал шаблоны, то их можно было бы использовать только в конструкторе, не выполняя что-то вроде LEDBitmap<5, 5> image = ..., а просто используя LEDBitmap image = LEDBitmap<5, 5>(...)

Я не смог использовать векторы так как они не являются частью Arduino IDE, которая написана на C. У меня есть моя библиотека на C ++, потому что я использую некоторые другие библиотеки, которые находятся на C ++ и изначально хотели использовать другую платформу, но из-за некоторых проблем, с которыми я столкнулсянедавно переключиться на Arduino.

В настоящее время я получаю сообщение об ошибке: no known conversion for argument 3 from 'uint8_t [3][3] {aka unsigned char [3][3]}' to 'uint8_t (*)[8] {aka unsigned char (*)[8]}'

Заранее благодарен за советы и помощь.

1 Ответ

0 голосов
/ 31 мая 2018

C ++ не любит массивы переменной длины (никогда не определяемые в стандарте, даже если поддерживается в некоторых реализациях), а также необработанные 2D-массивы.Если вам не требуется истинная [] поддержка оператора, я советую использовать функции доступа:

class Array2D {
    size_t width, height;
    uint8_t *data;

public:
    Array2D(size_t width, size_t height): width(width), height(height() {
        data = new uint8_t[width * height];
    }
    ~Arrayt2D() {
        delete[] data;
    }
    // copy/move ctor-assignment operator omitted for brievety but REQUIRED (law of three/five)

    uint8_t getVal(size_t i, size_t j) const {
        return data[i + j * width];
    }
    uint8_t setVal(uint8_t val, size_t i, size_t j) {
        data[i + j * width] = val;
    }
    /* alternatively to use arr.val(i, j) = value :
    uint8_t& val(size_t i, size_t j) {
        return data[i + j * width];
    }
    */
    // other accessors (height, width) omitted but probably useful...
};

Скорее C-ish, но поскольку вы не можете использовать векторы и предпочитаете избегать шаблонов, это может бытьосновной скелет ...

...