簡體   English   中英

帶有數組的Arduino C ++類

[英]Arduino C++ class with arrays

我正在建立一個應該包含數組的類。 我目前正在嘗試傳遞一個數組,但是該數組可以是任何大小。 當我嘗試這樣做時,它不起作用。 有誰知道該怎么做? 我目前遇到了一些麻煩,但這是我的代碼:

Relay.cpp

Relay::Relay(short pins[])
{
    _relay = pins;
    _binding = new short[length()];
    for(short i=0; i<length(); i++)
        _binding[i]=0;
}

short Relay::length()
{
    return sizeof(_relay)/sizeof(short);
}

Relay.h

class Relay
{
    public:
        Relay(short pins[]);
        short length();
    private:
        short *_relay;
        short *_binding;
};

當我創建實例時:

Relay reles((short[]){11, 10, 9, 8, 7, 3, 2, 73, 4, A0, A1, A2, A3, A4});

編輯:在常駐餅干的建議之后,我最終得到了像這樣的cpp文件,但它給了我對`operator new [](unsigned int)錯誤的未定義引用。 此外,當我嘗試訪問_pins並顯示_pins [i]中使用的內容時,它不會顯示我在實例上傳遞的內容。 例如,如果我顯示_pins [0]上的內容,則應返回11,但不是。

如果要使用此方法,則需要分配一些內存。

_bindings = new short[size];

完成操作后,請不要忘記釋放此內存。

delete[] _bindings;

在C ++中的動態數組位於名稱vector下。 您撥打的電話將變成:

class Relay
{
    public:
        Relay(const std::vector<short> &pins) 
           : _binding(pins.size()), _relay(pins) {}
    private:
        std::vector<short> _relay;
        std::vector<short> _binding;
};


int main() {
  // C++ 11
  //  Relay r({1, 2, 3, 4});

  // C++03
  short arr[] = {1, 2, 3, 4};
  std::vector<short> v(std::begin(arr), std::end(arr));
  Relay r(v);
}

您的代碼中存在多個問題,例如:

short *_relay;

是一個指針,sizeof(_relay)是指針的大小,與它指向的內存分配的大小無關。 所以sizeof(_relay)/ sizeof(short); 等價於sizeof(short *)/ sizeof(short); 這真的沒有任何意義。

當您這樣做時:

_relay = _pins;

您正在復制一個指針,現在_relay指向同一位置_pins點。 但是,他們指向的內存是“易失性”的:這是您在呼叫站點分配的臨時內存。 呼叫返回后,它將立即取消分配。 您的指針現在指向您不應再訪問的區域。

通常,使C ++類包含指向“外部數據”的指針是可疑的類設計。 通常,更好的方法是讓C ++使用外部數據的副本,因此很明顯,當銷毀類實例時,內存將被取消分配。

就像其他人提到的那樣,其中某些事情使用C ++ 11更容易完成。 如果您使用g++clang++作為編譯器,則可能已經支持C ++ 11,這使很多事情變得非常輕松便捷,尤其是對於嵌入式系統而言。

在這種特殊情況下,這是一個完整且可編譯的程序(我使用g++並使用g++ -std=c++11 -o relay relay.cpp進行了g++ -std=c++11 -o relay relay.cpp ,並將以下內容作為relay.cpp的內容。我將所有內容組合為一個為了簡化說明,請使用單個文件,但在現實生活中,應將已經擁有的.cpp.h文件分開。

#include #include

class Relay
{
    public:
        Relay(std::vector<short> pins)
            : _relay(pins), _binding(pins.size()) {}
        // these are just diagnostics for testing the class
        std::ostream& printPins(std::ostream &out) {
                for (auto i : _relay) 
                      out << i << ' '; 
                   out << std::endl; 
        }
        std::ostream& printBindings(std::ostream &out) { 
                for (auto i : _binding) 
                    out << i << ' '; 
                out << std::endl; 
        }
    private:
        std::vector<short> _relay;
        std::vector<short > _binding;
};

enum {A0=80, A1, A2, A3, A4};

int main()
{
    Relay reles{std::vector<short>{11, 10, 9, 8, 7, 3, 2, 73, 
                                 4, A0, A1, A2, A3, A4}};
    reles.printPins(std::cout);
    reles.printBindings(std::cout);
    return 0;
}

在此示例中, A0A4行的enum僅是為了完整性,但它們可能是#defineconst int聲明。 沒關系

這兩個print...()函數僅用於說明它實際上正在按預期進行。 在這種情況下,輸出為:

11 10 9 8 7 3 2 73 4 80 81 82 83 84 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 

std :: vector是標准庫的一部分,即使您沒有使用C ++ 11,也可以使用它。 如果您願意,那么您可以利用諸如移動語義和constexpr之類的有趣事物以及嵌入式系統中特別有用的其他優點。 這樣的一個不錯的功能稱為列表初始化,並在此示例程序的main中使用。 在這一行:

    Relay reles{std::vector<short>{11, 10, 9, 8, 7, 3, 2, 73, 4, A0, A1, A2, A3, A4}};

創建一個臨時的std::vector<short> ,然后將其用於初始化reles類實例化。 在某些情況下,聰明的編譯器可以優化此類臨時文件的創建。 與往常一樣,查看實際的匯編語言輸出對於評估特定技術和特定編譯器很有用。

我發現非常有用的另一件事是for循環的for (auto i : _relay)樣式。 這告訴編譯器通過將relay視為某物的集合來自動推斷i的類型。 非常簡潔,非常方便。

如果您還不熟悉C ++語言(或者只是相對較新的部分),我建議您買一本書,例如Stroustrup的The C ++ Programming Language,第四版。

編輯 :在不幸的情況下,您的C ++編譯器非常有限,就像Arduino 的情況一樣 ,您將需要做不同的事情。 具體來說,因為您沒有operator newoperator delete您必須為數組預先分配一些最大大小,或者僅依賴於初始化過程中傳入的數組。 這是一種方法:

#include <cassert>

class Relay
{
    public:
        Relay(int numpins, short *pins, short *bindings)
            : _numpins(numpins), _relay(pins), _binding(bindings) {}
    short pin(int i) 
    {
    if ((i < 0) || (i >= _numpins))
        return -1;
    return _relay[i];
    }
    short binding(int i)
    {
    if ((i < 0) || (i >= _numpins))
        return -1;
    return _binding[i];
    }
    private:
        int _numpins;
        short *_relay;
        short *_binding;
};

enum {A0=80, A1, A2, A3, A4};

int main()
{
    const int numpins = 14;
    short pins[numpins] = {11, 10, 9, 8, 7, 3, 2, 73, 
                           4, A0, A1, A2, A3, A4};
    short bindings[numpins] = {1, 2, 3, 4, 5, 6, 7,
                           8, 9, 10, 11, 12, 13, 14};
    Relay reles(numpins, pins, bindings);
    assert(reles.pin(0) == 11);
    assert(reles.binding(4) == 5);

    return 0;
}

暫無
暫無

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

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