vendredi 7 mai 2021

Fixing error "undefined reference to "Class::Function" in C++ VSCode [duplicate]

I'm fairly new to C++ and programming as a whole so I've never ran into a such issue and have been stuck for several hours without any idea how to solve it.

I'm trying to make a vector class by myself for a university project because we can't use the <vector> library.

Here's my code:

Vector.h

#pragma once
#include <iostream>

template <typename T>
class Vector {
private:
   T* data;
   size_t size;
   size_t capacity;

   void resize();

public:
   Vector();
   Vector(const Vector<T>& other);
   Vector& operator=(const Vector<T>& other);
   ~Vector();

   void push_back(T element);
   void pop_back();
   void push_front(T element);
   
   bool is_empty() const;
   void print() const;

   T& operator[](size_t index);
   const T& operator[](size_t index) const;

};

Vector.cpp

#include "Vector.h"

template <typename T>
void Vector<T>::resize() {
   this->capacity *= 2;
   T* temp = new T[this->capacity];

   for(size_t i = 0; i < this->size; ++i) {
      temp[i] = this->data[i];
   }
   delete[] this->data;
   this->data = temp;
}

template <typename T>
Vector<T>::Vector() {
   this->size = 0;
   this->capacity = 0;
   this->data = new T[this->capacity];
}

template <typename T>
Vector<T>::Vector(const Vector<T>& other) {
   this->capacity = other.capacity;
   this->size = other.size;
   this->data = new T[other.capacity];
   for(size_t i = 0; i < this->size; ++i) {
      this->data[i] = other.data[i];
   }
}

template <typename T>
Vector<T>& Vector<T>::operator=(const Vector<T>& other) {
   if(this != &other) {
      delete[] this->data;

      this->capacity = other.capacity;
      this->size = other.size;
      this->data = new T[other.capacity];
      for(size_t i = 0; i < this->size; ++i) {
         this->data[i] = other.data[i];
      }
   }

   return *this;
}

template <typename T>
Vector<T>::~Vector() {
   delete[] this->data;
}

template <typename T>
void Vector<T>::push_back(T element) {
   this->size++;
   if(this->size >= this->capacity) {
      this->resize();
   }

   this->data[this->size - 1] = element;
}

template <typename T>
void Vector<T>::pop_back() {
   if(this->size == 0) {
      std::cerr << "The vector is empty" << std::endl;
      return;
   }

   T* new_array = new T[this->size - 1];
   for(size_t i = 0; i < this->size - 1; ++i) {
      new_array[i] = this->data[i];
   }

   delete[] this->data;
   --this->size;
   this->data = new_array;
}

template <typename T>
void Vector<T>::push_front(T element) {
   this->size++;
   if(this->size >= this->capacity) {
      this->resize();
   }

   for(size_t i = this->size - 1; i > 0; --i) {
      this->data[i] = this->data[i - 1];
   }
   this->data[0] = element;
}

template <typename T>
bool Vector<T>::is_empty() const {
   if(this->size == 0) {
      return true;
   }
   else {
      return false;
   }
}

template <typename T>
void Vector<T>::print() const {
   for(size_t i = 0; i < this->size; ++i) {
      std::cout << this->data[i] << ", ";
   }
}

template <typename T>
T& Vector<T>::operator[](size_t index) {
   return this->data[index];
}

template <typename T>
const T& Vector<T>::operator[](size_t index) const {
   return this->data[index];
}

main.cpp

#include "Vector.h"

int main () {
   Vector<int> vec;
   vec.push_back(1);
   vec.push_back(2);
   vec.push_back(3);
   vec.push_back(4);
   vec.push_front(0);
   vec.pop_back();
   vec.print();
}

I'm trying to run it to test how it works but I'm getting these errors:

PS C:\projects\my-project> cd "c:\projects\my-project\"; if ($?) { g++ main.cpp -o main } ; if ($?) { .\main }
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x1b): undefined reference to `Vector<int>::Vector()'       
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x2c): undefined reference to `Vector<int>::push_back(int)' 
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x3d): undefined reference to `Vector<int>::push_back(int)' 
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x4e): undefined reference to `Vector<int>::push_back(int)' 
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x5f): undefined reference to `Vector<int>::push_back(int)' 
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x70): undefined reference to `Vector<int>::push_front(int)'
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x7c): undefined reference to `Vector<int>::pop_back()'   
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x88): undefined reference to `Vector<int>::print() const'
C:\Users\Name\AppData\Local\Temp\ccE3Cxfs.o:main.cpp:(.text+0x94): undefined reference to `Vector<int>::~Vector()'    
collect2.exe: error: ld returned 1 exit status

I read quite a few articles here and on other forums but nothing seems to help me. I tried fixing the tasks.json file by changing ${file} to ${workspaceFolder}/*.cpp as it was suggested here, tried to manually type the name of the file in the terminal like it was said here and here but nothing fixes the problem.

The only way to make it work is to include Vector.cpp instead of Vector.h in main.cpp but from what I've read and have been told, including .cpp files instead of the .h files is always a bad practice especially in big projects.

I'm probably missing something obvious but I would be thankful if someone can help me

Aucun commentaire:

Enregistrer un commentaire