C++:编译的程序和 CodeBlocks 上的 运行 工作但从终端它给出错误声明

C++ : A program compiled and run on CodeBlocks works but from Terminal it gives error statement

我本应该用来制作 C++ 项目的虚拟机出现了一些问题,它定期在 DevC++ CodeBlocks 上编译(发现了!),运行并完全按照它的意思去做。 无论如何,我试图从终端开始执行,但它崩溃并显示以下消息:

main.cpp:(.text.startup+0x1586): undefined reference to `move_red(vettore<vettore<blue_car> >*, vettore<vettore<red_car> >*, unsigned int, unsigned int, unsigned int*)'

(其实不同方法报错,但报错问题是一样的)

在终端中,我使用以下命令执行:

chmod +x build.sh; $ g++ -O2 -std=c++11 -o output main.cpp

这是涉及的函数:

void move_red(vettore<vettore<blue_car> > * v_col, vettore< vettore< red_car> > * v_row,unsigned int M,unsigned int N,unsigned int *n){

 vettore<blue_car> * pb;
 vettore<red_car> * pr;
 for(unsigned int kk=0;kk<M;kk++){ 

              pr=&((*v_row)[kk]); 
              for(unsigned int ll=0;ll<n[kk];ll++){
                           (pr->get_obj()).set_bloc(is_bloc_r(pr,&((*v_row)[kk]),v_col));
                           pr=pr->get_next(); 
                           }
              }
 for(unsigned int kk=0;kk<M;kk++){

              pr=&((*v_row)[kk]); 
              unsigned int ll;
              for(ll=0;ll<n[kk]-1;ll++){ 
                           if ((pr->get_obj().get_bloc()==0)) pr->get_obj().move_red();
                           pr=pr->get_next();
                           }
                           if((pr->get_obj().get_j()==N-1)&&((pr->get_obj().get_bloc()==0))){ 
                                     pr->get_obj().move_red_border();
                                     ((*v_row)[kk]).order(); 
                                    }
                           else if((pr->get_obj().get_bloc()==0)){
                                pr->get_obj().move_red(); 
                                }
              }
 };


void move_blue(vettore<vettore<blue_car> > * v_col, vettore< vettore< red_car> > * v_row,unsigned int M,unsigned int N,unsigned int *m){

     vettore<blue_car> * pb;
     vettore<red_car> * pr;

     for(unsigned int ll=0;ll<N;ll++){

          pb=&((*v_col)[ll]); 
          for(unsigned int kk=0;kk<m[ll];kk++){
                   (pb->get_obj()).set_bloc(is_bloc_b(pb,&((*v_col)[ll]),v_row));
                   pb=pb->get_next();
                   }
      }

     for(unsigned int ll=0;ll<N;ll++){

          pb=&((*v_col)[ll]);
          unsigned int kk;
          for(/*unsigned int */kk=0;kk<m[ll]-1;kk++){ 
                       if ((pb->get_obj().get_bloc()==0)&&pb->get_next()!=nullptr) pb->get_obj().move_blue();
                       pb=pb->get_next();
                       }
                       if((pb->get_obj().get_i()==M-1)&&((pb->get_obj().get_bloc()==0))){                                          pb->get_obj().move_blue_border();
                                 ((*v_col)[ll]).order(); 
                                }
                       else if((pb->get_obj().get_bloc()==0)){
                            pb->get_obj().move_blue();
                            }

          }
};

如果需要,这是主要的:

int main(int argc, char *argv[]){
bool error=0;
ifstream file("problem.csv");
if(file.fail()) {
                error=1;

                }
unsigned int N = 0;
unsigned int M = 0;
char c; 

int i=-1,j=0, k=0, n_iter, j_temp =0;

vettore<blue_car>  vb; 
vettore<red_car>  vr;

vettore< vettore <red_car> > v_row(vr); 
vettore< vettore <blue_car> > v_col(vb);
vettore<unsigned int> iter(0); 

std::string iterazioni;
std::string iteraz;

if(!error){

                    std::getline(file,iterazioni,'\n'); 
                    stringstream it(iterazioni);       
                      while (it.good() && i==-1) {
                                       std::getline(it,iteraz, ','); 
                                       iter[k] = atoi(iteraz.c_str());
                                                  if(iter[k]<0){
                                                                 error=1;
                                                                 break;
                                                                    }

                                        iter.append(0); 
                                                  k++;

                                }
                                    iter.remove_tail();

                                    i=0;
                                    n_iter=iter.get_size();

                                    }

if(!error){

while(file.get(c) && !error)
                  {

                        if((v_row.get_size()<i+1)||(v_col.get_size()<j+1)){
                                                                        if(i==0) {j_temp=v_col.get_size();}
                                                                        while(v_row.get_size()<1+i){
                                                                                               v_row.insert_tail(vr); 
                                                                                               }
                                                                        while(v_col.get_size()<j+1){
                                                                                                    v_col.insert_tail(vb); 
                                                                                                     }
                                                                        }

                        if (c=='1'){
                                   if(v_col[j].get_size()==1 && ((v_col[j])[0]).has_sense()==0){
                                                             v_col[j][0].set_2(i,j);
                                                             }
                                   else{
                                       blue_car * add_b = new blue_car;
                                       add_b->set_2(i,j);
                                       (v_col[j]).insert_tail(*add_b); 
                                       delete add_b;
                                       }
                                   }

                        if (c=='2'){
                                    if(v_row[i].get_size()==1 && ((v_row[i])[0]).has_sense()==0){
                                                             v_row[i][0].set_2(i,j);
                                                             }
                                    else{
                                         red_car * add_r = new red_car;
                                         add_r->set_2(i,j);
                                         (v_row[i]).insert_tail(*add_r); 
                                         delete add_r;
                                         }
                                    }



                        if (c==',') j++;

                        if (c=='\n'){
                                     i++;
                                     if (j != j_temp){
                                                      error=1;
                                                     break;
                                                     }
                                     j=0;
                                     }


                        if ((c!='\n') && (c!=',') && (c!='0') && (c!='1') && (c!='2')){
                                                                                      error=1;
                                                                                     break;
                                                                                     }
                        //n_iter = k-1;
                        N=v_col.get_size();
                        M=v_row.get_size();

                       }


    file.close();

                 }


 //n_iter =iter.get_size();
 M=v_row.get_size();
 N=v_col.get_size();
 unsigned int *n= new unsigned int[M];
 unsigned int *m= new unsigned int[N];
 for(int i=0;i<M;i++) n[i]=v_row[i].get_size();
 for(int i=0;i<N;i++) m[i]=v_col[i].get_size();


 unsigned int * iter_a= new unsigned int[iter.get_size()];
 for(unsigned int y=0;y<n_iter;y++) iter_a[y]=iter[y];

 std::sort(iter_a, iter_a + n_iter);

 unsigned int temp_iniz_iter = 0; 
 unsigned int temp_fine_iter;// = iter_a[0]; 
 for(int volte = 0; volte < n_iter; volte ++) { 
    temp_fine_iter = iter_a[volte]; 
    for(int iter__ = temp_iniz_iter; iter__ < temp_fine_iter; iter__ ++) {/
            if(temp_iniz_iter % 2){
                              move_red(&v_col,&v_row,M,N,n); 
                              iter__++; 
                              if(iter__<temp_fine_iter) move_blue(&v_col,&v_row,M,N,m); 
                              }
            else{
                 move_blue(&v_col,&v_row,M,N,m); 
                 iter__++; 
                 if(iter__<temp_fine_iter) move_red(&v_col,&v_row,M,N,n); 

                 }
            }
    print_csv(temp_fine_iter, &v_row, M, &v_col, N);
    temp_iniz_iter = temp_fine_iter; 

                            }
    //print_csv(temp_fine_iter, &v_row, M, &v_col, N);


delete[] iter_a;
/*if(!error) std::cout<<"Il programma Ë terminato con successo\a"<<endl;
else std::cout<<"Il programma Ë terminato con errori"<<endl;
system("PAUSE");*/
return EXIT_SUCCESS;
}

这些是我的 类:

template<class T> class vettore{
      private:
              T my_object; //container
              vettore <T> * next; //puntatore al prossimo elemento della lista
      public:
             vettore():next(nullptr){}; //default constructor
             vettore(T oggetto, vettore <T> * successivo=nullptr):next(successivo),my_object(oggetto){}; //faccio puntare la lista a quell'elemento 

             vettore(const vettore <T> &x):next(x.next),my_object(x.my_object){}; //copy constructor

             ~vettore(){//destructor
                       if(next!=nullptr){
                                         delete next;
                                         delete this;
                                         }
                       };



          vettore <T> * get_next(){
                  return next;};

          T get_my(){return my_object;};

          vettore<T> * ret_punt(unsigned int n){
                     if(n==0) return this;
                     if(n>=this->get_size()){std::cout<<"FUORI"<<std::endl;
                                                                           return this;}
                     vettore<T> * p=this;
                     for(unsigned int i=0;i<n;i++) p=p->get_next();
                     return p;
                     };

          T& get_obj(){ //ottenere l'oggetto by reference
                      return my_object;
                      };       
          vettore& operator=(vettore &x){ //overloading dell'operatore =
                  if(this!=nullptr) delete this;
                  unsigned int n;
                  n=x.get_size();

                  for(int i=0;i<n;i++){
                          (*this).insert_tail(x[i]);
                          }
                  return *this; //ritorna la cosa cui sta puntando this
                  };

          void ordina(){

               //vettore<T>*new_this=this;
               vettore<T>*aux=this;
               vettore<T>*punt_a_min=aux;
               bool sentinella=0;
               T min=aux->get_my();
               while(aux->get_next()!=nullptr){
                                               aux=aux->get_next();
                                               if(aux->get_my()<min){
                                                                   sentinella=1;  
                                                                   min=aux->get_my();
                                                                   punt_a_min=aux;
                                                                   }

                                               }
               if(sentinella==1){ 
                                 punt_a_min->set_obj(this->get_my());              
                                 this->set_obj(min);
                                 }
               if(this->get_next()!=nullptr) *(this->get_next()).ordina();                  
               };

          void set_next(vettore<T>*e){
               next=e;
               }

          void set_obj(T obj){
               my_object=obj;
               };

          void order(){
               unsigned int n=(*this).get_size();
               if(n==2){
                        T * p=new T;
                        p[0]=next->get_my();
                        next->set_obj(my_object);
                        my_object=p[0];
                        }
               if(n>2){
                   T * p=new T[n];
                   vettore<T> * aux=this;
                   for(unsigned int i=0;i<n;i++){
                                p[i]=aux->get_my();
                                aux=aux->get_next();
                                //I++
                                }
                   aux=this;
                   for(unsigned int i=0;i<n-1;i++){
                                aux=aux->get_next();
                                aux->set_obj(p[i]);
                                }
                   this->set_obj(p[n-1]);
                   delete []p;
                   }
               };

          void append(T obj){
               vettore<T> * aux=this;
               while(aux->get_next()!=nullptr) aux=aux->get_next();
               aux->set_next(new vettore <T>); //lo faccio puntare da aux->next al posto di nullptr ~ next=&v
               aux=aux->get_next();
               aux->set_obj(obj);
               aux->set_next(nullptr);
               };

          void insert_tail(T obj){
               vettore<T> * aux=this;
               while(aux->get_next()!=nullptr) aux=aux->get_next();

                    aux->set_next(new vettore <T>);
                    aux=aux->get_next();
                    aux->set_obj(obj);
                    aux->set_next(nullptr);
               };



          void remove_tail(){
               vettore<T> * aux=this;
               while(aux->get_next()->get_next()!=nullptr) aux=aux->get_next();
               delete aux->get_next();
               aux->set_next(nullptr);
               };

          unsigned int get_size(){
                   if(this==nullptr) return 0;
                   if(this->next==nullptr) return 1;
                   return 1+(*(this->next)).get_size();
                   };


          bool has_sense(){
              return 1;
              };

          T& operator[](unsigned int n){ 
                   if(this->get_size()-1<n) std::cout<<"elemento non accessibile"<<std::endl;
                   if(n==0) return my_object;
                   else{
                        vettore<T> * aux=this;
                        for(int ii=0;ii<n;ii++) aux=aux->get_next();
                        return aux->get_obj();        
                                }
                                };
          };
class car {

  protected:
            int i;
            int j;
            bool bloc;
  public:

         car():i(-1),j(-1),bloc(0){}; //default constructor
         car(int i,int j,bool bloc):i(i),j(j),bloc(bloc){}; //first constructor
         car(int i,int j):i(i),j(j),bloc(0){}; //second constructor
         car(const car & un_altro):i(un_altro.i),j(un_altro.j),bloc(un_altro.bloc){}; //copy constructor
         virtual ~car(){}; //destructor
         car &operator=(const car &x){
             i=x.i;
             j=x.j;
             bloc=x.bloc;
             return *this;
             };


         void set_i(int a){
              i=a;
              };

         void set_j(int b){
              j=b;
              };

         void set_bloc(bool c){
              bloc=c;
              };

         void set_2(int a, int b){
              i=a;
              j=b;
              };

         void set_3(int a, int b,bool c){
              i=a;
              j=b;
              bloc=c;
              };     
         int get_i(){
             return i;
             };

         int get_j(){
             return j;
             };

         bool get_bloc(){
              return bloc;
              };
         //print

         bool has_sense(){
              return(i>=0 && j>=0);
              };



         virtual void print(){
                 std::cout<<"Questa car si trova in posizione ("<<i<<","<<j<<") ed è "<<bloc<<"*bloccata"<<std::endl;
                 };
         };






class red_car:public car{


public:
    red_car():car(){};
    red_car(int i,int j, bool bloc):car(i,j,bloc){};
    red_car(int i, int j):car(i,j){};
    red_car(const red_car & un_altro):car(un_altro){}; //copy constructor ereditato

    red_car &operator=(const red_car &x){
             i=x.i;
             j=x.j;
             bloc=x.bloc;
             return *this;
             };

    void move_red(){
         if(j>=0) j++;
         bloc=0;
         };         

    bool has_sense(){
              return(i>=0 && j>=0);
              };

    void move_red_border(){
         if(j>=0) j=0;
         bloc=0;
         };          
    }; 

class blue_car:public car{


public:
    blue_car():car(){};
    blue_car(int i,int j, bool bloc):car(i,j,bloc){};
    blue_car(int i, int j):car(i,j){};
    blue_car(const blue_car & un_altro):car(un_altro){}; //copy constructor ereditato

    blue_car &operator=(const blue_car &x){
             i=x.i;
             j=x.j;
             bloc=x.bloc;
             return *this;
             };

    void move_blue(){
         if(i>=0) i++;
         bloc=0;
         };

    bool has_sense(){
              return(i>=0 && j>=0);
              };

    void move_blue_border(){
         if(i>=0) i=0;
         bloc=0;
         };                              
                 };

你能告诉我发生了什么事吗?

感谢您的宝贵时间。

我认为错误出在您用于手动构建项目的命令中:

$ g++ -O2 -std=c++11 -o output main.cpp

相反,您需要发出以下命令:

$ g++ -O2 -std=c++11 -o output main.cpp <where_move_red_and_blue_are_defined.cpp>

如果函数 void move_red(/*...*/)void move_blue(/*...*/) 是在 main.cpp 以外的源文件中定义的,则会发生您得到的错误,即链接错误。原因是,编译器看不到函数的 定义 ,只有 声明 ,它很可能位于 header 中。因此,当编译器在 main() 代码中看到对函数的调用时,结果很好 - 声明就足够了(声明已找到,因为您已将 *.hpp 文件包含到 main.cpp), 但是当谈到链接时,即将多个 .o object 文件连接成一个可执行文件时,会发生错误,因为没有指示在哪里可以找到 object 定义函数的文件。