0

I am doing some homework in C++ and I just encountered an error I couldn't fix. I defined a RingBuffer class that stores values, the logic works but I have a problem with the includes. If I don't include the .cpp file with the implementation of the methods I get an "undefined reference to function" error for every single function I defined.

rbtest.cpp (This class was given and is used to test the implementation)

#include <iostream>
#include <stdexcept>

#include "ringbuffer.hpp"

int main(void) {
    RingBuffer<int, 3> rb;
    rb.print();
    std::cout << std::boolalpha;
    std::cout << "Empty: " << rb.empty() << " Full: " << rb.full() << std::endl;
    rb.push_back(2);
    std::cout << "Empty: " << rb.empty() << " Full: " << rb.full() << std::endl;
    rb.push_front(1);
    rb.push_back(3);
    std::cout << "Empty: " << rb.empty() << " Full: " << rb.full() << std::endl;
    rb.push_back(4);
    std::cout << "Empty: " << rb.empty() << " Full: " << rb.full() << std::endl;
    rb.print();
    std::cout << "pop_front: " << rb.pop_front() << std::endl;
    std::cout << "Empty: " << rb.empty() << " Full: " << rb.full() << std::endl;
    std::cout << "pop_front: " << rb.pop_front() << std::endl;
    rb.push_back(5);
    rb.print();
    std::cout << "pop_back: " << rb.pop_back() << std::endl;
    std::cout << "pop_back: " << rb.pop_back() << std::endl;
    rb.print();
    try {
        rb.pop_back();
        std::cout << "This should not be printed!" << std::endl;
    }
    catch (std::exception& rangeError) {
        std::cout << "Error: " << rangeError.what() << std::endl;
    }
}

ringbuffer.hpp

#ifndef X

#define X
#include <iostream>
#include <stdexcept>

/**
 * @brief Ring Buffer class
 *
 * @tparam T typename
 * @tparam size int
 */
template <typename T, int size>
class RingBuffer {

private:
    int back = 0, front = 0;
    T content[size];
    int counter = 0;

public:



    void push_back(T item);

    void push_front(T item);

    T pop_back();

    T pop_front();

    bool full();
    bool empty();


    void print();

};
#endif

ringbuffer.cpp

#include "ringbuffer.hpp"

/**
 * @brief Pushes an Item into the ring buffer from the back
 *
 * @tparam T
 * @tparam size
 * @param item
 */
template <typename T, int size>
void RingBuffer<T, size>::push_back(T item) {
    if (full()) return;

    content[back] = item;
    back++;
    if (back == size) back = 0;
    counter++;

}
/**
 * @brief Pushes an item into the ring buffer from the front
 *
 * @tparam T
 * @tparam size
 * @param item
 */
template <typename T, int size>
void RingBuffer<T, size>::push_front(T item) {
    if (full()) return;

    front--;
    if (front < 0) front = size - 1;
    content[front] = item;
    counter++;

}
/**
 * @brief Pops an Item from the back and returns it
 *
 * @tparam T
 * @tparam size
 * @return T
 */
template <typename T, int size>
T RingBuffer<T, size>::pop_back() {
    if (empty()) {
        throw std::out_of_range("pop_back on empty buffer");

    }
    back--;
    if (back < 0) back = size - 1;
    T item = content[back];

    counter--;

    return item;
}
/**
 * @brief Pops an Item from the front and returns it
 *
 * @tparam T
 * @tparam size
 * @return T
 */
template <typename T, int size>
T RingBuffer<T, size>::pop_front() {
    if (empty()) {
        throw std::out_of_range("pop_front on empty buffer");

    }
    T item = content[front++];
    if (front == size) front = 0;
    counter--;

    return item;

}

/**
 * @brief Checks if ring buffer is full
 *
 * @tparam T
 * @tparam size
 * @return true if full
 * @return false if not full
 */
template <typename T, int size>
bool RingBuffer<T, size>::full() {
    return counter == size;
}

/**
 * @brief Checks if ring buffer is empty
 *
 * @tparam T
 * @tparam size
 * @return true if empty
 * @return false if not empty
 */
template <typename T, int size>
bool RingBuffer<T, size>::empty() {

    return counter == 0;
}

/**
 * @brief Prints the ring buffer with all its elements front to back, prints "Buffer is empty" if empty
 *
 * @tparam T
 * @tparam size
 */
template <typename T, int size>
void RingBuffer<T, size>::print() {

    if (empty()) std::cout << "Buffer is empty" << std::endl;
    else {
        int i = front;
        do {



            std::cout << content[i++] << "\t";

            if (i >= size) i = 0;



        } while (i != back);

        std::cout << std::endl;


    }


}

Makefile

all: rbtest.cpp ringbuffer.hpp ringbuffer.cpp
    g++ -o ringbuffer rbtest.cpp ringbuffer.hpp ringbuffer.cpp
clean:
    rm ringbuffer
Kunait
  • 31
  • 4

0 Answers0