How to implemet copy constructor in C++ - c++

this is the header of a class that I have been designing for an assignment. I have included constructors, a destructors, as well as overloaded operators. Could you give me a hint how to properly define the constructors in a class using c++ 20 most recent features in an efficient way.
#ifndef VECTOR_DOUBLE_H
#define VECTOR_DOUBLE_H
#include <memory>
#include <vector>
class vector_double {
public:
vector_double(int size);
vector_double(std::initializer_list<double> lst);
vector_double(const double* array, int size);
vector_double(const vector_doubler& other);
vector_doubleoperator=(const vector_double& other);
// because I use a managed pointer I don't need a destructor
~vector_double() noexcept = default;
void set(int index, double val);
double& get(int index);
const double& get(int index) const;
int size() const;
void reset(double val);
void fill_from(std::initializer_list<double> lst);
void fill_from(const double* array, int size);
int copy_to(std::vector<double>& vec) const;
double& operator[](int index);
const double& operator[](int index) const;
operator double() const;
vector_double add(const vector_double& other) const;
vector_doubleadd(double number) const;
vector_doublemul_by(double number) const;
void resize(int size);
friend std::ostream& operator<<(std::ostream& out, const vector_double& vec);
private:
std::unique_ptr<double[]> m_array;
int m_size;
};
inline std::ostream& operator<<(std::ostream& out, const vector_double& vec){
if (vec.m_size == 0){
out << "{ }";
}
else{
auto first = true;
out << '{';
for (int i=0; i < vec.m_size; ++i){
if (!first)
out << ", ";
else
first = !first;
out << vec.m_array[i];
}
out << '}';
}
return out;
}
#endif //VECTOR_DOUBLE_H

This example definition may help, I tried sticking to C++20 features:
#include <cmath>
#include "vector_double.h"
vector_double::vector_double(int size):
m_array{ new double[size] },
m_size{size}
{}
vector_double::vector_double(std::initializer_list<double> lst): //Constructor that takes an init list
vector_double(lst.size())
{
std::copy(lst.begin(), lst.end(), m_array.get());
}
vector_double::vector_double(const double* array, int size): //Constructor that takes array and size
vector_double(size)
{
// std::copy(array, array + size, m_array.get());
std::copy(&array[0], &array[size], m_array.get());
}
vector_double::vector_double(const vector_double& other): //Copy Constructor
vector_double(other.m_size)
{
std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
}
vector_double& vector_double::operator=(const vector_double& other) {
if (this != &other) {
if (m_size != other.m_size) {
auto* array = new double[other.m_size];
m_array.reset(array);
m_size = other.m_size;
}
std::copy(&other.m_array[0], &other.m_array[m_size], &m_array[0]);
}
return *this;
}
void vector_double::set(int index, double val) {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
m_array[index] = val;
}
double& vector_double::get(int index) {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
return m_array[index];
}
const double& vector_double::get(int index) const {
if (index < 0 || index > m_size)
throw std::out_of_range("oooh my!");
return m_array[index];
}
int vector_double::size() const {
return m_size;
}
void vector_double::reset(double val) {
for (int i=0; i<m_size; ++i){
m_array[i] = val;
}
}
void vector_double::fill_from(std::initializer_list<double> lst) {
int size = std::min((int)lst.size(), m_size);
std::copy(lst.begin(), lst.begin() + size, &m_array[0]);
}
void vector_double::fill_from(const double* array, int size) {
size = std::min(size, m_size);
for (int i = 0; i < size; ++i) {
m_array[i] = array[i];
}
}
int vector_double::copy_to(std::vector<double>& vec) const {
for (int i = 0; i < m_size; ++i) {
vec.push_back(m_array[i]);
}
return m_size;
}
double& vector_double::operator[](int index) {
return m_array[index];
}
const double& vector_double::operator[](int index) const { //Overloading "[]" operator
return m_array[index];
}
vector_double::operator double() const {
double sum = 0.0;
for (int i = 0; i < m_size; ++i) {
sum += m_array[i] * m_array[i];
}
return std::sqrt(sum);
}
vector_double vector_double::add(const vector_double& other) const {
if (m_size != other.m_size)
throw std::logic_error("size mismatch");
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] += other[i];
}
return copy;
}
vector_double vector_double::add(double number) const {
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] += number;
}
return copy;
}
vector_double vector_double::mul_by(double number) const {
auto copy = *this;
for (int i = 0; i < m_size; ++i) {
copy[i] *= number;
}
return copy;
}
void vector_double::resize(int size) {
if (size != m_size){
auto array = new double[size] {0,};
auto common = std::min(size,m_size);
for (int i = 0; i < common; ++i) {
array[i] = m_array[i];
}
m_array.reset(array);
m_size = size;
}
}

Related

I can change the values even when I use const word with my own array class template

So I'm trying to write my own array template and everything works until i try to create a const object of my class template. in main.cpp I create the object with the copy contructor and I change it which I would expect to not work but it works. Help would be appreciated :D
main.cpp
# include "Array.hpp"
int main( void ) {
Array<int> l = 1;
l.setValue(5, 0);
const Array<int> abc(l);
std::cout << abc[0] << std::endl;
abc[0] = 3;
std::cout << abc[0] << std::endl;
return (0);
}
Array.tpp
#ifndef ARRAY_TPP
# define ARRAY_TPP
# include "Array.hpp"
template<class T>
class Array {
private:
int size_;
T *array_;
public:
Array() : size_(0), array_(new T[size_]) {};
Array(int n) : size_(n), array_(new T[size_]) {};
Array(Array const& src) : size_(src.size()), array_(new T[src.size()]) {
for (int i = 0; i < src.size(); ++i) {
array_[i] = src[i];
}
};
Array& operator=(Array const& copy) {
size_ = copy.size();
delete[] array_;
array_ = new T[size_];
for (int i = 0; i < size_; i++)
array_[i] = copy[i];
return (*this);
}
T& operator[](int n) const {
if (n < 0 || n >= size_)
throw std::out_of_range("out of range");
return (array_[n]);
}
int size(void) const { return (size_); };
void setValue(T value, int n) {
if (n < 0 || n >= size_)
throw std::out_of_range("out of range");
array_[n] = value;
}
~Array() { delete[] array_; };
};
#endif
The issue is this:
T& operator[](int n) const {
if (n < 0 || n >= size_)
throw std::out_of_range("out of range");
return (array_[n]);
}
Because this is declared to be a const method, it can be called on a const Array. Though, it returns a non-const reference to the element. Because Array stores the elements via a T *, only that pointer is const in a const Array while modifiying the elements via that pointer is "fine".
You need two overloads of operator[]:
T& operator[](int n);
const T& operator[](int n) const;

Getting error in merging two arrays in c++?

I am trying to merge two dynamic arrays but I am getting an error in my merge function that
"data': is not a member of 'List<T>"
I know that the error is ocuring because the given parameter in the merge(const List& other) is list but I am confused how to access my ArrayList2 which has been passed in merge function in the main
my code is:
#include <iostream>
using namespace std;
template<class T>
class List {
public:
// return the capacity of the list
virtual size_t capacity() const = 0;
// return the number of elements in the list
virtual size_t size() const = 0;
// inserts an element to the beginning
virtual void push_front(const T& value) = 0;
// adds an element to the end
virtual void push_back(const T& value) = 0;
// removes the last element
virtual void pop_back() = 0;
// removes the first element
virtual void pop_front() = 0;
// remove the first occurrence of an element with the given value
virtual void remove(const T& val) = 0;
// merges two sorted lists
virtual void merge(const List<T>& other) = 0;
virtual ~List() {}
};
template<class T>
class ArrayList : public List<T>
{
private:
T* data;
size_t max_capacity;
size_t num_of_element;
public:
ArrayList() = delete; // disable default constructor
// constructor
ArrayList(size_t capacity) : max_capacity(capacity), num_of_element(0) {
data = new T[capacity];
}
// copy constructor
ArrayList(const ArrayList<T>& other_list) : max_capacity(other_list.max_capacity),
num_of_element(other_list.num_of_element) {
data = new T[max_capacity];
for (size_t i = 0; i < other_list.num_of_element; i++) {
data[i] = other_list.data[i];
}
}
// destructor
virtual ~ArrayList() {
delete[]data;
}
size_t capacity() const override {
return max_capacity;
}
size_t size() const override {
return num_of_element;
}
T& operator[](int index) {
return data[index];
}
bool operator==(const ArrayList<T>& other_list) {
// not comparing capacity as eventually array list can be made capacity irrelevant using dynamic allocation
if (num_of_element != other_list.num_of_element) {
return false;
}
for (int i = 0; i < num_of_element; i++) {
if (data[i] != other_list.data[i]) {
return false;
}
}
return true;
}
void push_front(const T& value)
{
}
void push_back(const T& value)
{
if (max_capacity > num_of_element)
{
num_of_element++;
data[num_of_element - 1] = value;
}
}
void pop_back()
{
}
void pop_front()
{
}
void remove(const T& val)
{
int i = 0, j;
while (i < max_capacity)
{
if (data[i] == val)
{
for (int j = i; j < num_of_element-1; j++)
data[j] = data[j + 1];
if (data[i] == val && (i + 1) > num_of_element - 1)
{
data[i] = {};
num_of_element--;
break;
}
num_of_element--;
}
else
i++;
}
}
void merge(const List<T>& other)
{
int i;
int newsize = size() + other.size();
T* temp = new T[newsize];
for (i = 0; i < num_of_element; i++)
temp[i] = data[i];
for (int j = 0; j < other.size(); j++)
{
temp[i] = other.data[j]; //I am getting error on this line
i++;
}
}
private:
void shift_left_to(size_t start) {
for (size_t i = start; i < num_of_element - 1; i++) {
data[i] = data[i + 1];
}
}
};
int main() {
ArrayList<int> list1(3);
list1.push_back(3);
list1.push_back(1);
list1.push_back(1);
ArrayList<int> list2(2);
list2.push_back(1);
list2.push_back(8);
list1.merge(list2);
/* for (size_t i = 0; i < list1.size(); i++)
cout<<list1[i]<<" ";
cout<<"Size:"<<list1.size()<<" Capacity:"<<list1.capacity();*/
system("pause");
return 0;
}
Presumably, all of your concrete List<T> classes (e.g. ArrayList<T>) will have some kind of accessors to the elements. You can make those accessors part of the List<T> interface and call them in the implementation of void merge(List<T> const&). As an example:
template <class T>
class List {
public:
// ...
virtual T& operator[](int index) = 0;
virtual T const& operator[](int index) const = 0;
};
template <class T>
class ArrayList : public List<T> {
private:
T* data;
size_t max_capacity;
size_t num_of_element;
public:
// ...
T& operator[](int index) override { return data[index]; }
T const& operator[](int index) const override { return data[index]; }
// ...
void merge(const List<T>& other) {
int i;
int newsize = size() + other.size();
T* temp = new T[newsize];
for (i = 0; i < num_of_element; i++) temp[i] = data[i];
for (int j = 0; j < other.size(); j++) {
temp[i] = other[j]; // < Use your List<T>::operator[] here
i++;
}
}
// ...
};
I'd say the message is quite descriptive: List does not have a member called data. You should use the [] operator instead to access the list elements in the merge function. [] operator is implemented by descendants of List.
temp[i] = other[j]

(c++) stl vector implemenation

I've implemented a simple vector-like structure
It works well if i use vector<int> or vector<char>
but when i use <vector<vector<int>> it makes error
Is there are good implementation code about vector stl or problem in my code?
here is my code
class _vector {
private:
int _size;
int _capacity;
T* vc;
public:
_vector(int size = 1) {
_size = 0;
_capacity = size;
vc = new T[size];
}
~_vector() {
delete[] vc;
}
int size() { return _size; }
bool empty() { return !_size; }
void resize(int size) {
_capacity = size;
T* tmp = new T[size];
for (int i = 0; i < _size; i++) tmp[i] = vc[i];
delete[] vc;
vc = tmp;
}
void clear() {
delete[] vc;
_capacity = 1;
_size = 0;
vc = new T[_capacity];
}
void push_back(T val) {
if (_size == _capacity) resize(2 * _capacity);
vc[_size++] = val;
}
void pop_back() {
if (_size == 0) return;
vc[--_size] = 0;
}
T& operator[](int i) const { return vc[i]; }
_vector<T>& operator=(_vector<T> &tmp) {
_capacity = tmp._capacity;
_size = tmp._size;
delete[] vc;
vc = new T[_capacity];
for (int i = 0; i < _size; i++) vc[i] = tmp[i];
return *this;
}
Your implementation is not following the Rule of 3, as it is missing a copy constructor, and a proper copy assignment operator (which can be implemented utilizing the copy constructor). And in C++11 and later, the Rule of 5, by adding a move constructor and a move assignment operator.
Also, your implementation does not work correctly with non-trivial types that have constructors/destructors defined, such as when T is another _vector type, or any other type that has pointers/resources allocated inside of it. So, your class needs to construct new objects when adding elements to the array, using placement-new, and destruct objects when removing elements from the array, by directly calling their destructors.
Try something more like this instead:
template <typename T>
class _vector {
public:
typedef unsigned int size_type;
typedef T value_type;
private:
size_type _size;
size_type _capacity;
value_type* vc;
public:
_vector(size_type initalcap = 0) : _size(0), _capacity(0), vc(0) {
reserve(initialcap);
}
_vector(const _vector<T> &src) : _size(0), _capacity(0), vc(0) {
reserve(src._capacity);
for(size_type i = 0; i < src._size; ++i) {
new(vc[i]) value_type(src.vc[i]);
}
_size = src._size;
}
// C++11 and later only...
_vector(_vector<T> &&src) : _size(src._size), _capacity(src._capacity), vc(src._vc) {
src._size = 0;
src._capacity = 0;
src.vc = 0;
}
~_vector() {
clear();
delete[] reinterpret_cast<char*>(vc);
}
size_type size() const { return _size; }
size_type capacity() const { return _capacity; }
bool empty() const { return !_size; }
void reserve(size_type newcap) {
if (newcap <= _capacity) return;
value_type* tmp = reinterpret_cast<value_type*>(new char[sizeof(value_type) * newcap]);
for (size_type i = 0; i < _size; ++i) {
new(tmp[i]) value_type(vc[i]);
}
delete[] reinterpret_cast<char*>(vc);
vc = tmp;
_capacity = newcap;
}
void resize(size_type newsize) {
if (newsize < _size) {
for(size_type i = _size; i-- > newsize; ) {
vc[i].~value_type();
}
_size = newsize;
}
else if (newsize > _size) {
reserve(newsize);
for (size_type i = _size; i < newsize; ++i) {
new(vc[i]) value_type();
}
_size = newsize;
}
}
void clear() {
resize(0);
}
void push_back(const T &val) {
if (_size == _capacity) reserve(2 * _capacity);
new(vc[_size]) value_type(val);
++_size;
}
void pop_back() {
if (_size) {
vc[--_size].~value_type();
}
}
value_type& operator[](size_type i) { return vc[i]; }
const value_type& operator[](size_type i) const { return vc[i]; }
_vector<T>& operator=(const _vector<T> &rhs) {
if (&rhs != this) {
_vector<T> tmp(rhs);
std::swap(tmp.vc, vc);
std::swap(tmp._size, _size);
std::swap(tmp._capacity, _capacity);
}
return *this;
}
// C++11 and later only...
_vector<T>& operator=(_vector<T> &&rhs) {
_vector<T> tmp(std::move(rhs));
std::swap(tmp.vc, vc);
std::swap(tmp._size, _size);
std::swap(tmp._capacity, _capacity);
return *this;
}
};

Printing unexpected blank lines and crash

For a school project I need to make a constructor with a recursive sort function that is given from a teacher in it, with a few function that I had to make myself. When I start the program the result shows a few blank lines and then the expected output. But when I increase int_buffer a(100) or higher and trys again the program just crashes. I think it might be memory leak, but not quite sure and don't know how to fix the problem either. I think that the problem is in int_sorted.cpp
Code:
main.cpp:
#include "int_buf.h"
#include "int_sorted.h"
#include <iostream>
#include <string>
void f(int_buffer& buf){
for (int* i = buf.begin();i != buf.end();i++) {
}
for (const int* i = buf.begin(); i != buf.end(); i++) {
}
}
int main(){
int_buffer a(100);
int_buffer b(50);
int r[] = {1,4,10,2,54,3,6,20};
for (size_t i = 0; i < a.size(); i++){
a[i] = std:: rand();
b[i] = std::rand();
}
int_sorted x(a.begin(), a.size());
}
std::cout << "\n";*/
for (int i = 0; i < x.size();i++) {
std::cout<<*(x.begin() + i)<<"\n";
return 0;
}
int_buf.h:
#ifndef INT_BUF_H
#define INT_BUF_H
#include <cstdlib>
class int_buffer {
public:
bool check_sorted(int_buffer int_check);
explicit int_buffer(size_t size);
int_buffer(const int * source, size_t size);
int_buffer(const int_buffer & rhs);
int_buffer(int_buffer && rhs);
int_buffer & operator =(const int_buffer & rhs);
int_buffer & operator =(int_buffer && rhs);
int& int_buffer::operator[](size_t index);
size_t size() const;
int * begin();
int * end();
const int* begin() const;
const int* end() const;
~int_buffer();
private:
size_t sz;
int* buf;
};
#endif
int_buf.cpp:
#include "int_buf.h"
#include <algorithm>
#include <iostream>
#include <cstddef>
bool int_buffer::check_sorted(int_buffer int_check){
int* a = int_check.begin();
int* b = nullptr;
while (a != int_check.end() -1){
b= a + 1;
if (*a > *b){
return false;
}
else{
a = b;
}
}
return true;
}
int_buffer::int_buffer(size_t size) :sz(size), buf(new int[size]){}
int_buffer::int_buffer(const int* source, size_t size) : sz(size), buf(new int[size]){
for (size_t i = 0; i < sz;i++){
buf[i] = *(source+i);
}
}
int_buffer::int_buffer(const int_buffer& rhs):sz(rhs.sz),buf(new int[rhs.sz]){
std::copy(rhs.begin(), rhs.end(), begin());
}
int_buffer::~int_buffer(){
delete[] buf;
}
int_buffer::int_buffer(int_buffer && rhs) :buf(nullptr), sz(0){
std::swap(buf, rhs.buf);
std::swap(sz, rhs.sz);
}
int_buffer& int_buffer::operator =(const int_buffer & rhs){
int_buffer temp(rhs);
std::swap(temp.buf,buf);
std::swap(temp.sz,sz);
return *this;
}
int_buffer & int_buffer::operator =(int_buffer&& rhs){
std::swap(buf, rhs.buf);
std::swap(sz, rhs.sz);
return *this;
}
int& int_buffer::operator[](size_t index){
return buf[index];
}
size_t int_buffer::size() const{
return sz;
}
int* int_buffer::begin(){
return buf;
}
int* int_buffer::end(){
return buf + sz;
}
const int* int_buffer::begin() const{
return buf;
}
const int* int_buffer::end() const{
return buf + sz;
}
int_sorted.h:
#ifndef INT_SORTED_H
#define INT_SORTED_H
#include "int_buf.h"
#include <iostream>
class int_sorted{
public:
int_sorted(const int* source, std::size_t size);
std::size_t size() const;
int* insert(int value);
const int* begin() const;
const int* end() const;
int_sorted merge(const int_sorted& merge_with) const;
int_sorted sort(const int*begin, const int* end);
void int_sorted::selSort(int_sorted& arr, int size);
private:
int_buffer buffer;
};
#endif
int_sorted.cpp:
#include "int_sorted.h"
#include "int_buf.h"
#include <iostream>
#include <algorithm>
#include <cstddef>
int_sorted::int_sorted(const int* source, size_t size) :buffer(source, size){
if (buffer.size() < 1) {}
else {
if (buffer.check_sorted(buffer)) {}
else {
int_buffer tmp(buffer.begin(), 0);
tmp = sort(buffer.begin(), buffer.end()).buffer;
buffer = tmp;
}
}
}
size_t int_sorted::size() const{
return buffer.size();
}
int* int_sorted::insert(int value) {
int_buffer tmp(buffer.size()+1);
for (int i =0; i < buffer.size();i++) {
tmp[i] = buffer[i];
}
tmp[buffer.size()] = value;
this->buffer = tmp;
return (buffer.end()-1);
}
const int* int_sorted::begin() const{
return buffer.begin();
}
const int* int_sorted::end() const{
return buffer.end();
}
int_sorted int_sorted::merge(const int_sorted& merge_with) const{
int_sorted c(this->begin(), 0);
const int* travA = this->begin();
const int* travB = merge_with.begin();
int tCountA = 0;
int tCountB = 0;
while ((travA + tCountA)!=this->end()&&(travB + tCountB )!=merge_with.end()){
if (travA[tCountA] < travB[tCountB]){
c.insert(travA[tCountA]);
tCountA++;
}
else{
c.insert(travB[tCountB]);
tCountB++;
}
}
while ((travA + tCountA)!=this->end()){
c.insert(travA[tCountA]);
tCountA++;
}
while ((travB + tCountB) != merge_with.end()){
c.insert(travB[tCountB]);
tCountB++;
}
std::cout << "\n";
return c;
}
int_sorted int_sorted::sort(const int* begin, const int* end) {
if (begin == end)return int_sorted(begin, 1);
if (begin == end - 1)return int_sorted(begin, 1);
ptrdiff_t half = (end - begin) / 2;
const int* mid = begin + half;
return sort(begin, mid).merge(sort(mid, end));
}
This is what it looks like when I have int_buffer a(20);
unexpected blank lines

Invalid operands to binary expression while implementing vector [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
In an assigment, I was asked to create my own Vector<T>, Mathvector<T> (which inherits from vector) and a Polynomial class type.
I'm getting the following error and couldn't figure out why.
MathVector.h:37:32: error: invalid operands to binary expression ('mathVector<double>' and 'mathVector<double>')
if (this[j]>this[j+1])
Ihe sort function is in "mathVector.h" and its goal is to sort the vector in ascending or descending order.
This is the error part of the "MathVector.h":
void sort(int index) {
int i,j;
int n=this->get_size();
if (index==1) {
for (i=0; i<n-1; i++)
for (j=0; j<n-i-1; j++) {
if (this[j]>this[j+1]) {
T temp;
temp=this[j+1];
this[j+1]=this[j];
this[j]=temp;
}
}
}
else {
for (i=0; i<n-1; i++)
for (j=0; j<n-i-1; j++) {
if (this[j]<this[j+1]) {
T temp;
temp=this[j+1];
this[j+1]=this[j];
this[j]=temp;
}
}
}
return;
}
This is the "vector.h":
template<class T>
class Vector {
private:
int _size;
int _capacity;
T *_data;
static T *allocate(int size) {
return static_cast<T *>(malloc(sizeof(T) * size));
}
static void copyRange(T *begin, T *end, T *dest) {
while (begin != end) {
new((void *) dest) T(*begin);
++begin;
++dest;
}
}
static void deleteRange(T *begin, T *end) {
while (begin != end) {
begin->~T();
++begin;
}
}
public:
Vector() {
_size = 0;
_capacity = 0;
_data = 0;
}
~Vector() {
deleteRange(_data, _data + _size);
free(_data);
}
Vector(const Vector &obj) {
this->_size = obj.get_size();
this->_data = obj.get_data();
this->_capacity = obj.get_capacity();
}
void insert(const T &value) {
if (_size != _capacity) {
new((void *) (_data + _size)) T(value);
++_size;
return;
}
int newCapacity;
if (_capacity == 0) { newCapacity = 1; }
else (newCapacity = _capacity * 2);
T *newData = allocate(newCapacity);
copyRange(_data, _data + _size, newData);
new((void *) (newData + _size)) T(value);
deleteRange(_data, _data + _size);
free(_data);
_data = newData;
_capacity = newCapacity;
++_size;
}
void resize(int index) {
if (index == _capacity) { return; }
else if (index > _capacity) { _capacity = index; }
else {
_capacity = index;
if (index < _size) {
deleteRange(_data + index, _data + _size);
_size = index;
}
}
}
T &operator[](int index) {
T empty;
if ((index < 0) || (index >= _size)) {
cout<<"Wrong Index";
return empty;
}
return _data[index];
}
const T &
operator[](int index) const {
T empty;
if ((index < 0) || (index >= _size)) {
cout<<"Wrong Index";
return empty;
} else return _data[index];
}
Vector &operator=(const Vector &other) {
this->_size = other.get_size();
this->_data = other.get_data();
this->_capacity = other.get_capacity();
return *this;
}
friend ostream &operator<<(ostream &os, const Vector &other) {
os << "Size: " << other._size << " | Capacity: " << other._capacity << " | ";
int i;
for (i = 0; i < other._size; i++) {
os << other[i] << ",";
}
return os;
}
T *begin() const {
return _data;
}
T *end() const {
return _data + _size;
}
int get_size() const {
return _size;
}
T* get_data() const {
return _data;
}
int get_capacity() const {
return _capacity;
}
};
this[j] is hardly ever the right thing to do. It can only be correct, if *this happens to be a subobject within an array, and have at least j siblings after it. this[j] is equivalent to *(this + j). As you can see, it dereferences a pointer to jth sibling after *this.
I suspect, that you instead intended to access the elements of the buffer by calling Vector::operator[]. You'd do that by dereferencing the pointer first: (*this)[j].