C++ 编译错误:";对列表的未定义引用<;脉宽调制>;::AList();Arduino C++;

C++ 编译错误:";对列表的未定义引用<;脉宽调制>;::AList();Arduino C++;,c++,arduino,C++,Arduino,我使用为Arduino创建了一个双链接列表,但是在定义它时,我得到了编译错误。这个库不是我写的,其他人也成功地使用了它,所以我认为这不是问题所在,但我的代码才是问题所在。我也在使用Arduino IDE,所以我假设这不是链接器错误。这是我的主文件(main.ino): 项目h: #include "Arduino.h" #include "AList.h" #include "PWM.h" //other stuff PWM.h: #ifndef PWM_H #define PWM_H cl

我使用为Arduino创建了一个双链接列表,但是在定义它时,我得到了编译错误。这个库不是我写的,其他人也成功地使用了它,所以我认为这不是问题所在,但我的代码才是问题所在。我也在使用Arduino IDE,所以我假设这不是链接器错误。这是我的主文件(main.ino):

项目h:

#include "Arduino.h"
#include "AList.h"
#include "PWM.h"
//other stuff
PWM.h:

#ifndef PWM_H
#define PWM_H

class Pwm{
  public:
  static AList<Pwm> pwms;
  static int numPwms;
  //other stuff
};

#endif
\ifndef PWM\u H
#定义PWM_H
类脉宽调制{
公众:
静态pwms;
静态int-numPwms;
//其他东西
};
#恩迪夫
PWM.cpp:

#include "project.h"

int Pwm::numPwms = 0;
AList<Pwm> Pwm::pwms;
//other stuff
#包括“project.h”
int Pwm::numPwms=0;
脉冲宽度调制:脉冲宽度调制;
//其他东西
A.h:

#ifndef ALIST_H
#define ALIST_H

template <typename ListItem>
class AList{

private:
    /** Intended for private representation of a ListItem within the AList class - Internal use only!
    @author Marco Bertschi
    */
    struct PrivateListItem{
        PrivateListItem* prv;
        PrivateListItem* nxt;
        ListItem crnt;
    };

    PrivateListItem* last;      //!< The last item of the list.
    PrivateListItem* first;     //!< The first item of the list.
    int count;                  //!< Zero-based count of items within the list.

public:
    AList();
    ~AList();
    ListItem First();
    ListItem Last();

    int Count();
    void Add(ListItem listItem);
    void RemAt(int index);
    ListItem GetAt(int index);
    void Clr();
};

#endif //ALIST_H
\ifndef ALIST\H
#定义
样板
阶级主义者{
私人:
/**用于AList类中ListItem的私有表示-仅供内部使用!
@作家马可·贝尔斯基
*/
私有结构{
私人机构*prv;
私有企业*nxt;
列表项crnt;
};
PrivateListItem*last;/!<列表的最后一项。
PrivateListItem*first;/!<列表的第一项。
int count;/!<列表中项目的零基计数。
公众:
AList();
~AList();
ListItem First();
ListItem Last();
int Count();
作废添加(列表项列表项);
无效重新匹配(整数索引);
列表项GetAt(int索引);
void Clr();
};
#endif//ALIST_H
最后,AList.cpp:

#include "AList.h"

//! Instantiates a new instance of an AList.
/*!
\return     AList<ListItem>     A new instance of an AList.
*/
template <typename ListItem>
AList<ListItem>::AList(){
    count = -1;
}
//! Destroys the instance of AList<ListItem>.
/*!
The AList<ListItem>::Clr() is called in order to free memory which
was previously occupied by the dynamically allocated list items.
\sa Clr();
*/
template <typename ListItem>
AList<ListItem>::~AList(){
    if (count > -1){
        Clr(); //Clear the List in order to free memory
    }
}
//! Adds an Item of the type ListItem to the AList.
/*!
\param      li      [ListItem]      The ListItem which is added to the AList.
\return     void    [void]      
*/
template <typename ListItem>
void AList<ListItem>::Add(ListItem li){
    PrivateListItem* pLItem = new PrivateListItem;
    pLItem->crnt = li;

    if (count > -1){
        pLItem->nxt = first;
        pLItem->prv = last;
        last->nxt = pLItem;
        last = pLItem;
        count++;
    }
    else if (count == -1){
        first = pLItem;
        first->nxt = pLItem;
        first->prv = pLItem;
        last = pLItem;
        last->nxt = pLItem;
        last->prv = pLItem;
        count = 0;
    }
}
//! Removes a ListItem from a given index position in the AList.
/*!
In case that there is no ListItem stored at the given index of the List 
no operation will be done and the list remains unchanged.

\param      index   [int]   The Index at which the ListItem gets removed.
\return     void    [void]
*/
template <typename ListItem>
void AList<ListItem>::RemAt(int index){
    if (index < count){
        PrivateListItem* pLItem = last;
        for (int i = 0; i <= index; i++){
            pLItem = pLItem->nxt;
        }
        pLItem->prv->nxt = pLItem->nxt;
        pLItem->nxt->prv = pLItem->prv;
        delete pLItem;
        count--;
    }
}
//! Gets a ListItem from a given index position in the AList.
/*!
In case that there is no ListItem stored at the given index of the List
this method will return a random value, or may lead to a Memory read exception.
This also applies if no item at all is stored in the list.

\param      index       [int]       The Index at which the ListItem gets removed.
\return     ListItem    [ListItem]  The ListItem at the position `index` in the list.
\sa Count()
*/
template <typename ListItem>
ListItem AList<ListItem>::GetAt(int index){
    PrivateListItem* pLItem = first;
    if (index <= count && index > -1){
        int i = 0;
        while(i < index){
            pLItem = pLItem->nxt;
            i++;
        }
    }

    return pLItem->crnt;
}
//! Gets the first ListItem which is stored in the list.
/*!
A random value will be returned if no items are stored in the list.

\return     ListItem    [ListItem]    The first ListItem in the list.
\sa Last(), Count()
*/
template <typename ListItem>
ListItem AList<ListItem>::First(){
    return first->crnt;
}
//! Gets the last ListItem which is stored in the list.
/*!
A random value will be returned if no items are stored in the list.
If there is only one Item stored in the list this method returns the same value as AList<ListItem>::First().

\return     ListItem    [ListItem]  The first ListItem in the list.
\sa First(), Count()
*/
template <typename ListItem>
ListItem AList<ListItem>::Last(){
    return last->crnt;
}
//! Gets the number of ListItems in the List.
/*!
The number is zero-based - A return value `0` means that there is one item stored in the list.
Please remember that a return value of `-1` means that there are no items stored in the list.

\return     int     [int]       Zero-based number of Items in the List.
*/
template <typename ListItem>
int AList<ListItem>::Count(){
    return count;
}

//! Clears the content of the List.
/*!

\return     void    [void]
*/
template <typename ListItem>
void AList<ListItem>::Clr(){
    PrivateListItem* pLItem = first;
    while(count > -1){
        PrivateListItem* tbdListItem = pLItem;
        pLItem = pLItem->nxt;
        delete tbdListItem;
        count--;
    }
}
#包括“AList.h”
//! 实例化列表的新实例。
/*!
\返回一个新的列表实例。
*/
样板
AList::AList(){
计数=-1;
}
//! 销毁了一个实例。
/*!
调用AList::Clr()以释放
以前被动态分配的列表项占用。
\sa-Clr();
*/
样板
AList::~AList(){
如果(计数>-1){
Clr();//清除列表以释放内存
}
}
//! 将ListItem类型的项添加到列表中。
/*!
\param li[ListItem]添加到列表中的ListItem。
\退回作废[作废]
*/
样板
作废列表::添加(列表项li){
PrivateListItem*pLItem=新的PrivateListItem;
pLItem->crnt=li;
如果(计数>-1){
pLItem->nxt=第一个;
pLItem->prv=最后一个;
最后->nxt=pLItem;
last=pLItem;
计数++;
}
否则如果(计数==-1){
第一个=pLItem;
第一->nxt=pLItem;
第一->prv=pLItem;
last=pLItem;
最后->nxt=pLItem;
最后->prv=pLItem;
计数=0;
}
}
//! 从列表中给定的索引位置删除列表项。
/*!
如果列表的给定索引中没有存储ListItem
不会执行任何操作,列表保持不变。
\param index[int]删除列表项的索引。
\退回作废[作废]
*/
样板
无效列表::重新映射(整型索引){
如果(索引<计数){
PrivateListItem*pLItem=最后一个;
对于(int i=0;i nxt;
}
pLItem->prv->nxt=pLItem->nxt;
pLItem->nxt->prv=pLItem->prv;
删除pLItem;
计数--;
}
}
//!从列表中给定的索引位置获取ListItem。
/*!
如果列表的给定索引中没有存储ListItem
此方法将返回一个随机值,或者可能导致内存读取异常。
如果列表中根本没有存储任何项,则此项也适用。
\param index[int]删除列表项的索引。
\返回列表项[ListItem]列表中“index”位置的列表项。
\sa计数()
*/
样板
ListItem列表:GetAt(int索引){
PrivateListItem*pLItem=第一个;
如果(索引-1){
int i=0;
而(inxt;
i++;
}
}
返回pLItem->crnt;
}
//!获取存储在列表中的第一个ListItem。
/*!
如果列表中未存储任何项目,则将返回一个随机值。
\返回列表项[ListItem]列表中的第一个ListItem。
\sa Last(),Count()
*/
样板
ListItem列表:First(){
返回第一->crnt;
}
//!获取存储在列表中的最后一个ListItem。
/*!
如果列表中未存储任何项目,则将返回一个随机值。
如果列表中只存储了一个项,则此方法返回与AList::First()相同的值。
\返回列表项[ListItem]列表中的第一个ListItem。
\sa First(),Count()
*/
样板
ListItem列表::Last(){
返回最后一个->crnt;
}
//!获取列表中ListItems的数目。
/*!
该数字以零为基础-返回值“0”表示列表中存储了一项。
请记住,返回值“-1”表示列表中没有存储任何项目。
\返回int[int]列表中基于零的项数。
*/
样板
int-AList::Count(){
返回计数;
}
//!清除列表的内容。
/*!
\退回作废[作废]
*/
样板
void::Clr(){
PrivateListItem*pLItem=第一个;
而(计数>-1){
privatestitem*tbdListItem=pLItem;
pLItem=pLItem->nxt;
删除tbdListItem;
计数--;
}
}
我的错误:

PWM.cpp.o: In function `__static_initialization_and_destruction_0':
PWM.cpp:4: undefined reference to `AList<Pwm>::AList()'
PWM.cpp:4: undefined reference to `AList<Pwm>::~AList()'
PWM.cpp.o:在函数“静态”初始化和“销毁”0中:
PWM.cpp:4:对'AList::AList()'的未定义引用
PWM.cpp:4:对'AList::~AList()的未定义引用

再次,AList是已知的工作而不是我的,但我把它包括在参考中。我已经看了关于这个错误的其他问题,而且它们似乎都不适用于我的问题。我理解这是一个复杂的问题,有很多代码,但是谢谢你们看它,帮助我。< /P> < P>在任何普通C++项目中,我建议PutTi。将整个

AList
放在它的头文件中;也就是说,取
AList.cpp
的内容并粘在
AList.h
的末尾

原因是许多C++编译器C
PWM.cpp.o: In function `__static_initialization_and_destruction_0':
PWM.cpp:4: undefined reference to `AList<Pwm>::AList()'
PWM.cpp:4: undefined reference to `AList<Pwm>::~AList()'
#ifndef MyClassName_h //If MyClassName_h "Not" DEFined
#define MyClassName_h //Then define MyClassName_h
class MyClassName{
  public:
    void get_computer_msg(boolean echo_cmd = false);
    String computer_msg;
    char first_char;
};
#endif //End if

#include "MyClassName.cpp" //Same as first answer recommends
#ifndef MyClassName_cpp //the _cpp is just to delineate between the two files  
#define MyClassName_cpp
#include "MyClassName.h"
void MyClassName::get_computer_msg(boolean echo_cmd) { //Receive message from computer
  int index = 0;
  String msg = "";
  String echo_msg = "";
  if(Serial.available()) {
    while(Serial.available()) {
      char cChar = Serial.read();
      msg += cChar;
      echo_msg += cChar;
      index++;
    }
    if(echo_cmd) Serial.println("Computer sent " + echo_msg + "+CRLF");
    first_char = msg.charAt(0);
    computer_msg = msg;
  }
}
#endif