A STL-like vector implementation in C++STL-like graph implementationVector implementation - simple replacementSTL vector implementationVector implementationVector Implementation C++Vector implementation in C++Custom STL Vector in C++A vector implementationModern Vector implementationC++ Updated Stack Code

Script executes loop only once

Variable dimensional integrals

How did researchers find articles before the Internet and the computer era?

Bin Packing with Relational Penalization

Can European countries bypass the EU and make their own individual trade deal with the U.S.?

How to describe POV characters?

Just graduated with a master’s degree, but I internalised nothing

Why wasn't EBCDIC designed with contiguous alphanumeric characters?

How could a satellite follow earth around the sun while staying outside of earth's orbit?

Could human civilization live 150 years in a nuclear-powered aircraft carrier colony without resorting to mass killing/ cannibalism?

13th chords on guitar

How did they film the Invisible Man being invisible, in 1933?

Can a stressful Wish's Strength reduction be cured early by a Greater Restoration spell?

I just started should I accept a farewell lunch for a coworker I don't know?

How can I deal with extreme temperatures in a hotel room?

Can a nowhere continuous function have a connected graph?

What is "oversubscription" in Networking?

How to unit test methods which using static methods?

Why wasn't ASCII designed with a contiguous alphanumeric character order?

Why did NASA wet the road in front of the Space Shuttle crawler?

Journal standards vs. personal standards

Company threatening to call my current job after I declined their offer

My colleague is constantly blaming me for his errors

What game is this character in the Pixels movie from?



A STL-like vector implementation in C++


STL-like graph implementationVector implementation - simple replacementSTL vector implementationVector implementationVector Implementation C++Vector implementation in C++Custom STL Vector in C++A vector implementationModern Vector implementationC++ Updated Stack Code






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








5












$begingroup$


I'm implementing a STL-like vector with the essential functionalities.



I would like to know what is good in this code and what is bad. In terms of everything (memory usage, functions implementations, naming conventions, etc,...).



The header:



#ifndef BVECTOR_H
#define BVECTOR_H

#include <memory>

static const int MIN_CAPACITY = 16;
static const int GROWTH_FACTOR = 2;
static const int SHRINK_FACTOR = 4;

class BVector

public:
BVector() = delete;
BVector(int);
BVector(int, int);
//BVector(const BVector&); //Copy Constructor
//BVector(const BVector&&); //Move Constructor

//BVector& operator=(BVector&); //Copy assignment operator.
//BVector& operator=(BVector&&); //Move assignment operator.

~BVector() = default;

int const& operator[] (int) const;
int& operator[](int);
int at(int);

void push(int);
int pop();
void insert(int, int);
void prepend(int);
bool find(int);
void Delete(int idx);

int size() const;
int capacity() const;
void resize(int);
bool isEmpty();


private:
int m_size0;
int m_capacityMIN_CAPACITY;

std::unique_ptr<int[]> m_data;

int DetermineCapacity(int);
void IncreaseCapacity();
void DecreaseCapacity();
;



#endif // BVECTOR_H



The implementation:



#include "bvector.h"
#include <iostream>

BVector::BVector(int capacity): m_size(0)

int new_capacity = DetermineCapacity(capacity);
m_data = std::unique_ptr<int[]>(new int[new_capacity]);


BVector::BVector(int capacity, int init_val)

int new_capacity = DetermineCapacity(capacity);
m_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < new_capacity; i++)

m_data[i] = init_val;



int const& BVector::operator[](int idx) const

return m_data[idx];


int& BVector::operator[](int idx)

return m_data[idx];


int BVector::at(int idx)

return m_data[idx];


void BVector::resize(int requiredSize)

if(m_size < requiredSize)

if(m_size == m_capacity)
IncreaseCapacity();
else if(m_size > requiredSize)

if(m_size < (m_capacity/SHRINK_FACTOR))
DecreaseCapacity();




int BVector::DetermineCapacity(int capacity)

int actual_capacity = MIN_CAPACITY;

while(capacity > (actual_capacity/GROWTH_FACTOR))

actual_capacity *= GROWTH_FACTOR;


return actual_capacity;


void BVector::IncreaseCapacity()

int old_capacity = m_capacity;
int new_capacity = DetermineCapacity(old_capacity);

if(new_capacity != old_capacity)

std::unique_ptr<int[]> new_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < m_size; i++)

new_data[i] = m_data[i];


m_capacity = new_capacity;

m_data = std::move(new_data);



void BVector::DecreaseCapacity()

int old_capacity = m_capacity;
int new_capacity = old_capacity / 2;

if(new_capacity < MIN_CAPACITY)
new_capacity = MIN_CAPACITY;

if(new_capacity != old_capacity)

std::unique_ptr<int[]> new_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < m_size; i++)

new_data[i] = m_data[i];


m_capacity = new_capacity;

m_data = std::move(new_data);



int BVector::capacity() const

return this->m_capacity;


int BVector::size() const

return this->m_size;


void BVector::push(int val)

resize(m_size + 1);
m_data[m_size] = val;
++m_size;


bool BVector::isEmpty()

return (m_size == 0);


int BVector::pop()

if(!this->isEmpty())

resize(m_size-1);
int value = m_data[m_size];
--m_size;
return value;
else

std::cout << "Nothing to pop." << std::endl;
exit(EXIT_FAILURE);



void BVector::insert(int value, int idx)

resize(m_size + 1);

std::unique_ptr<int[]> newData = std::unique_ptr<int[]>(new int[m_capacity]);

for (int i = 0; i < m_size+1; i++)

if(i == idx)

newData[i] = value;
newData[i+1] = m_data[i];

else if(i > idx)

newData[i+1] = m_data[i];

else

newData[i] = m_data[i];



m_data = std::move(newData);

++m_size;


void BVector::prepend(int value)

resize(m_size + 1);

for(int i = m_size; i > 0; i--)

m_data[i] = m_data[i - 1];


m_data[0] = value;

++m_size;


bool BVector::find(int reqVal)

for(auto i = 0; i < m_size; i++)

if(m_data[i] == reqVal)
return true;

return false;


void BVector::Delete(int idx)

resize(m_size - 1);

for(int i = idx; i < m_size - 1; i++)

m_data[i] = m_data[i+1];


--m_size;



The usage:



#include <iostream>
#include "bvector.h"

int main()

BVector vec(10);

std::cout << vec[3] << std::endl;

vec.push(10);
vec.push(20);
vec.push(30);
vec.push(40);
vec.push(50);
vec.push(60);
vec.push(70);
vec.push(80);
vec.push(90);
vec.push(100);
vec.push(110);
vec.push(120);
vec.push(130);
vec.push(140);
vec.push(150);
vec.push(160);
vec.push(170);
vec.push(180);

vec.insert(333, 8);

vec.Delete(8);

std::cout << vec[vec.size()-1] << std::endl;

vec[vec.size()-1] = 555;

std::cout << vec.at(vec.size()-1) << std::endl;

vec.prepend(987);

std::cout << vec.at(0) << std::endl;

std::cout << vec.at(1) << std::endl;

int x = vec.pop();

std::cout << "Popped Value: " << x << std::endl;

bool flg = vec.find(150);
std::cout << flg << std::endl;


return 0;



Any detailed notes is so much appreciated.










share|improve this question









$endgroup$











  • $begingroup$
    STL-like? Some parts of it are somewhat similar to a specific instantiation (std::vector<int>), but there are more differences.
    $endgroup$
    – Deduplicator
    Jun 20 at 17:52






  • 3




    $begingroup$
    If it's meant to be STL-like, I'd at least expect it to satisfy requirements of Container, be usable with algorithms, range-based for, etc... The interface should similar too, there are many odd names in your case.
    $endgroup$
    – Dan Mašek
    Jun 20 at 23:44










  • $begingroup$
    It also has no Allocator.
    $endgroup$
    – rubenvb
    Jun 21 at 8:43










  • $begingroup$
    A good read for sobody implementing the vector. I wrote four articles on how to do it. Vector - Resource Management Allocation Vector - Resource Management Copy Swap Vector - Resize Vector - Simple Optimizations
    $endgroup$
    – Martin York
    10 hours ago

















5












$begingroup$


I'm implementing a STL-like vector with the essential functionalities.



I would like to know what is good in this code and what is bad. In terms of everything (memory usage, functions implementations, naming conventions, etc,...).



The header:



#ifndef BVECTOR_H
#define BVECTOR_H

#include <memory>

static const int MIN_CAPACITY = 16;
static const int GROWTH_FACTOR = 2;
static const int SHRINK_FACTOR = 4;

class BVector

public:
BVector() = delete;
BVector(int);
BVector(int, int);
//BVector(const BVector&); //Copy Constructor
//BVector(const BVector&&); //Move Constructor

//BVector& operator=(BVector&); //Copy assignment operator.
//BVector& operator=(BVector&&); //Move assignment operator.

~BVector() = default;

int const& operator[] (int) const;
int& operator[](int);
int at(int);

void push(int);
int pop();
void insert(int, int);
void prepend(int);
bool find(int);
void Delete(int idx);

int size() const;
int capacity() const;
void resize(int);
bool isEmpty();


private:
int m_size0;
int m_capacityMIN_CAPACITY;

std::unique_ptr<int[]> m_data;

int DetermineCapacity(int);
void IncreaseCapacity();
void DecreaseCapacity();
;



#endif // BVECTOR_H



The implementation:



#include "bvector.h"
#include <iostream>

BVector::BVector(int capacity): m_size(0)

int new_capacity = DetermineCapacity(capacity);
m_data = std::unique_ptr<int[]>(new int[new_capacity]);


BVector::BVector(int capacity, int init_val)

int new_capacity = DetermineCapacity(capacity);
m_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < new_capacity; i++)

m_data[i] = init_val;



int const& BVector::operator[](int idx) const

return m_data[idx];


int& BVector::operator[](int idx)

return m_data[idx];


int BVector::at(int idx)

return m_data[idx];


void BVector::resize(int requiredSize)

if(m_size < requiredSize)

if(m_size == m_capacity)
IncreaseCapacity();
else if(m_size > requiredSize)

if(m_size < (m_capacity/SHRINK_FACTOR))
DecreaseCapacity();




int BVector::DetermineCapacity(int capacity)

int actual_capacity = MIN_CAPACITY;

while(capacity > (actual_capacity/GROWTH_FACTOR))

actual_capacity *= GROWTH_FACTOR;


return actual_capacity;


void BVector::IncreaseCapacity()

int old_capacity = m_capacity;
int new_capacity = DetermineCapacity(old_capacity);

if(new_capacity != old_capacity)

std::unique_ptr<int[]> new_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < m_size; i++)

new_data[i] = m_data[i];


m_capacity = new_capacity;

m_data = std::move(new_data);



void BVector::DecreaseCapacity()

int old_capacity = m_capacity;
int new_capacity = old_capacity / 2;

if(new_capacity < MIN_CAPACITY)
new_capacity = MIN_CAPACITY;

if(new_capacity != old_capacity)

std::unique_ptr<int[]> new_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < m_size; i++)

new_data[i] = m_data[i];


m_capacity = new_capacity;

m_data = std::move(new_data);



int BVector::capacity() const

return this->m_capacity;


int BVector::size() const

return this->m_size;


void BVector::push(int val)

resize(m_size + 1);
m_data[m_size] = val;
++m_size;


bool BVector::isEmpty()

return (m_size == 0);


int BVector::pop()

if(!this->isEmpty())

resize(m_size-1);
int value = m_data[m_size];
--m_size;
return value;
else

std::cout << "Nothing to pop." << std::endl;
exit(EXIT_FAILURE);



void BVector::insert(int value, int idx)

resize(m_size + 1);

std::unique_ptr<int[]> newData = std::unique_ptr<int[]>(new int[m_capacity]);

for (int i = 0; i < m_size+1; i++)

if(i == idx)

newData[i] = value;
newData[i+1] = m_data[i];

else if(i > idx)

newData[i+1] = m_data[i];

else

newData[i] = m_data[i];



m_data = std::move(newData);

++m_size;


void BVector::prepend(int value)

resize(m_size + 1);

for(int i = m_size; i > 0; i--)

m_data[i] = m_data[i - 1];


m_data[0] = value;

++m_size;


bool BVector::find(int reqVal)

for(auto i = 0; i < m_size; i++)

if(m_data[i] == reqVal)
return true;

return false;


void BVector::Delete(int idx)

resize(m_size - 1);

for(int i = idx; i < m_size - 1; i++)

m_data[i] = m_data[i+1];


--m_size;



The usage:



#include <iostream>
#include "bvector.h"

int main()

BVector vec(10);

std::cout << vec[3] << std::endl;

vec.push(10);
vec.push(20);
vec.push(30);
vec.push(40);
vec.push(50);
vec.push(60);
vec.push(70);
vec.push(80);
vec.push(90);
vec.push(100);
vec.push(110);
vec.push(120);
vec.push(130);
vec.push(140);
vec.push(150);
vec.push(160);
vec.push(170);
vec.push(180);

vec.insert(333, 8);

vec.Delete(8);

std::cout << vec[vec.size()-1] << std::endl;

vec[vec.size()-1] = 555;

std::cout << vec.at(vec.size()-1) << std::endl;

vec.prepend(987);

std::cout << vec.at(0) << std::endl;

std::cout << vec.at(1) << std::endl;

int x = vec.pop();

std::cout << "Popped Value: " << x << std::endl;

bool flg = vec.find(150);
std::cout << flg << std::endl;


return 0;



Any detailed notes is so much appreciated.










share|improve this question









$endgroup$











  • $begingroup$
    STL-like? Some parts of it are somewhat similar to a specific instantiation (std::vector<int>), but there are more differences.
    $endgroup$
    – Deduplicator
    Jun 20 at 17:52






  • 3




    $begingroup$
    If it's meant to be STL-like, I'd at least expect it to satisfy requirements of Container, be usable with algorithms, range-based for, etc... The interface should similar too, there are many odd names in your case.
    $endgroup$
    – Dan Mašek
    Jun 20 at 23:44










  • $begingroup$
    It also has no Allocator.
    $endgroup$
    – rubenvb
    Jun 21 at 8:43










  • $begingroup$
    A good read for sobody implementing the vector. I wrote four articles on how to do it. Vector - Resource Management Allocation Vector - Resource Management Copy Swap Vector - Resize Vector - Simple Optimizations
    $endgroup$
    – Martin York
    10 hours ago













5












5








5





$begingroup$


I'm implementing a STL-like vector with the essential functionalities.



I would like to know what is good in this code and what is bad. In terms of everything (memory usage, functions implementations, naming conventions, etc,...).



The header:



#ifndef BVECTOR_H
#define BVECTOR_H

#include <memory>

static const int MIN_CAPACITY = 16;
static const int GROWTH_FACTOR = 2;
static const int SHRINK_FACTOR = 4;

class BVector

public:
BVector() = delete;
BVector(int);
BVector(int, int);
//BVector(const BVector&); //Copy Constructor
//BVector(const BVector&&); //Move Constructor

//BVector& operator=(BVector&); //Copy assignment operator.
//BVector& operator=(BVector&&); //Move assignment operator.

~BVector() = default;

int const& operator[] (int) const;
int& operator[](int);
int at(int);

void push(int);
int pop();
void insert(int, int);
void prepend(int);
bool find(int);
void Delete(int idx);

int size() const;
int capacity() const;
void resize(int);
bool isEmpty();


private:
int m_size0;
int m_capacityMIN_CAPACITY;

std::unique_ptr<int[]> m_data;

int DetermineCapacity(int);
void IncreaseCapacity();
void DecreaseCapacity();
;



#endif // BVECTOR_H



The implementation:



#include "bvector.h"
#include <iostream>

BVector::BVector(int capacity): m_size(0)

int new_capacity = DetermineCapacity(capacity);
m_data = std::unique_ptr<int[]>(new int[new_capacity]);


BVector::BVector(int capacity, int init_val)

int new_capacity = DetermineCapacity(capacity);
m_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < new_capacity; i++)

m_data[i] = init_val;



int const& BVector::operator[](int idx) const

return m_data[idx];


int& BVector::operator[](int idx)

return m_data[idx];


int BVector::at(int idx)

return m_data[idx];


void BVector::resize(int requiredSize)

if(m_size < requiredSize)

if(m_size == m_capacity)
IncreaseCapacity();
else if(m_size > requiredSize)

if(m_size < (m_capacity/SHRINK_FACTOR))
DecreaseCapacity();




int BVector::DetermineCapacity(int capacity)

int actual_capacity = MIN_CAPACITY;

while(capacity > (actual_capacity/GROWTH_FACTOR))

actual_capacity *= GROWTH_FACTOR;


return actual_capacity;


void BVector::IncreaseCapacity()

int old_capacity = m_capacity;
int new_capacity = DetermineCapacity(old_capacity);

if(new_capacity != old_capacity)

std::unique_ptr<int[]> new_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < m_size; i++)

new_data[i] = m_data[i];


m_capacity = new_capacity;

m_data = std::move(new_data);



void BVector::DecreaseCapacity()

int old_capacity = m_capacity;
int new_capacity = old_capacity / 2;

if(new_capacity < MIN_CAPACITY)
new_capacity = MIN_CAPACITY;

if(new_capacity != old_capacity)

std::unique_ptr<int[]> new_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < m_size; i++)

new_data[i] = m_data[i];


m_capacity = new_capacity;

m_data = std::move(new_data);



int BVector::capacity() const

return this->m_capacity;


int BVector::size() const

return this->m_size;


void BVector::push(int val)

resize(m_size + 1);
m_data[m_size] = val;
++m_size;


bool BVector::isEmpty()

return (m_size == 0);


int BVector::pop()

if(!this->isEmpty())

resize(m_size-1);
int value = m_data[m_size];
--m_size;
return value;
else

std::cout << "Nothing to pop." << std::endl;
exit(EXIT_FAILURE);



void BVector::insert(int value, int idx)

resize(m_size + 1);

std::unique_ptr<int[]> newData = std::unique_ptr<int[]>(new int[m_capacity]);

for (int i = 0; i < m_size+1; i++)

if(i == idx)

newData[i] = value;
newData[i+1] = m_data[i];

else if(i > idx)

newData[i+1] = m_data[i];

else

newData[i] = m_data[i];



m_data = std::move(newData);

++m_size;


void BVector::prepend(int value)

resize(m_size + 1);

for(int i = m_size; i > 0; i--)

m_data[i] = m_data[i - 1];


m_data[0] = value;

++m_size;


bool BVector::find(int reqVal)

for(auto i = 0; i < m_size; i++)

if(m_data[i] == reqVal)
return true;

return false;


void BVector::Delete(int idx)

resize(m_size - 1);

for(int i = idx; i < m_size - 1; i++)

m_data[i] = m_data[i+1];


--m_size;



The usage:



#include <iostream>
#include "bvector.h"

int main()

BVector vec(10);

std::cout << vec[3] << std::endl;

vec.push(10);
vec.push(20);
vec.push(30);
vec.push(40);
vec.push(50);
vec.push(60);
vec.push(70);
vec.push(80);
vec.push(90);
vec.push(100);
vec.push(110);
vec.push(120);
vec.push(130);
vec.push(140);
vec.push(150);
vec.push(160);
vec.push(170);
vec.push(180);

vec.insert(333, 8);

vec.Delete(8);

std::cout << vec[vec.size()-1] << std::endl;

vec[vec.size()-1] = 555;

std::cout << vec.at(vec.size()-1) << std::endl;

vec.prepend(987);

std::cout << vec.at(0) << std::endl;

std::cout << vec.at(1) << std::endl;

int x = vec.pop();

std::cout << "Popped Value: " << x << std::endl;

bool flg = vec.find(150);
std::cout << flg << std::endl;


return 0;



Any detailed notes is so much appreciated.










share|improve this question









$endgroup$




I'm implementing a STL-like vector with the essential functionalities.



I would like to know what is good in this code and what is bad. In terms of everything (memory usage, functions implementations, naming conventions, etc,...).



The header:



#ifndef BVECTOR_H
#define BVECTOR_H

#include <memory>

static const int MIN_CAPACITY = 16;
static const int GROWTH_FACTOR = 2;
static const int SHRINK_FACTOR = 4;

class BVector

public:
BVector() = delete;
BVector(int);
BVector(int, int);
//BVector(const BVector&); //Copy Constructor
//BVector(const BVector&&); //Move Constructor

//BVector& operator=(BVector&); //Copy assignment operator.
//BVector& operator=(BVector&&); //Move assignment operator.

~BVector() = default;

int const& operator[] (int) const;
int& operator[](int);
int at(int);

void push(int);
int pop();
void insert(int, int);
void prepend(int);
bool find(int);
void Delete(int idx);

int size() const;
int capacity() const;
void resize(int);
bool isEmpty();


private:
int m_size0;
int m_capacityMIN_CAPACITY;

std::unique_ptr<int[]> m_data;

int DetermineCapacity(int);
void IncreaseCapacity();
void DecreaseCapacity();
;



#endif // BVECTOR_H



The implementation:



#include "bvector.h"
#include <iostream>

BVector::BVector(int capacity): m_size(0)

int new_capacity = DetermineCapacity(capacity);
m_data = std::unique_ptr<int[]>(new int[new_capacity]);


BVector::BVector(int capacity, int init_val)

int new_capacity = DetermineCapacity(capacity);
m_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < new_capacity; i++)

m_data[i] = init_val;



int const& BVector::operator[](int idx) const

return m_data[idx];


int& BVector::operator[](int idx)

return m_data[idx];


int BVector::at(int idx)

return m_data[idx];


void BVector::resize(int requiredSize)

if(m_size < requiredSize)

if(m_size == m_capacity)
IncreaseCapacity();
else if(m_size > requiredSize)

if(m_size < (m_capacity/SHRINK_FACTOR))
DecreaseCapacity();




int BVector::DetermineCapacity(int capacity)

int actual_capacity = MIN_CAPACITY;

while(capacity > (actual_capacity/GROWTH_FACTOR))

actual_capacity *= GROWTH_FACTOR;


return actual_capacity;


void BVector::IncreaseCapacity()

int old_capacity = m_capacity;
int new_capacity = DetermineCapacity(old_capacity);

if(new_capacity != old_capacity)

std::unique_ptr<int[]> new_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < m_size; i++)

new_data[i] = m_data[i];


m_capacity = new_capacity;

m_data = std::move(new_data);



void BVector::DecreaseCapacity()

int old_capacity = m_capacity;
int new_capacity = old_capacity / 2;

if(new_capacity < MIN_CAPACITY)
new_capacity = MIN_CAPACITY;

if(new_capacity != old_capacity)

std::unique_ptr<int[]> new_data = std::unique_ptr<int[]>(new int[new_capacity]);

for(int i = 0; i < m_size; i++)

new_data[i] = m_data[i];


m_capacity = new_capacity;

m_data = std::move(new_data);



int BVector::capacity() const

return this->m_capacity;


int BVector::size() const

return this->m_size;


void BVector::push(int val)

resize(m_size + 1);
m_data[m_size] = val;
++m_size;


bool BVector::isEmpty()

return (m_size == 0);


int BVector::pop()

if(!this->isEmpty())

resize(m_size-1);
int value = m_data[m_size];
--m_size;
return value;
else

std::cout << "Nothing to pop." << std::endl;
exit(EXIT_FAILURE);



void BVector::insert(int value, int idx)

resize(m_size + 1);

std::unique_ptr<int[]> newData = std::unique_ptr<int[]>(new int[m_capacity]);

for (int i = 0; i < m_size+1; i++)

if(i == idx)

newData[i] = value;
newData[i+1] = m_data[i];

else if(i > idx)

newData[i+1] = m_data[i];

else

newData[i] = m_data[i];



m_data = std::move(newData);

++m_size;


void BVector::prepend(int value)

resize(m_size + 1);

for(int i = m_size; i > 0; i--)

m_data[i] = m_data[i - 1];


m_data[0] = value;

++m_size;


bool BVector::find(int reqVal)

for(auto i = 0; i < m_size; i++)

if(m_data[i] == reqVal)
return true;

return false;


void BVector::Delete(int idx)

resize(m_size - 1);

for(int i = idx; i < m_size - 1; i++)

m_data[i] = m_data[i+1];


--m_size;



The usage:



#include <iostream>
#include "bvector.h"

int main()

BVector vec(10);

std::cout << vec[3] << std::endl;

vec.push(10);
vec.push(20);
vec.push(30);
vec.push(40);
vec.push(50);
vec.push(60);
vec.push(70);
vec.push(80);
vec.push(90);
vec.push(100);
vec.push(110);
vec.push(120);
vec.push(130);
vec.push(140);
vec.push(150);
vec.push(160);
vec.push(170);
vec.push(180);

vec.insert(333, 8);

vec.Delete(8);

std::cout << vec[vec.size()-1] << std::endl;

vec[vec.size()-1] = 555;

std::cout << vec.at(vec.size()-1) << std::endl;

vec.prepend(987);

std::cout << vec.at(0) << std::endl;

std::cout << vec.at(1) << std::endl;

int x = vec.pop();

std::cout << "Popped Value: " << x << std::endl;

bool flg = vec.find(150);
std::cout << flg << std::endl;


return 0;



Any detailed notes is so much appreciated.







c++ c++11 vectors






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jun 19 at 23:56









Bilal AhmedBilal Ahmed

906 bronze badges




906 bronze badges











  • $begingroup$
    STL-like? Some parts of it are somewhat similar to a specific instantiation (std::vector<int>), but there are more differences.
    $endgroup$
    – Deduplicator
    Jun 20 at 17:52






  • 3




    $begingroup$
    If it's meant to be STL-like, I'd at least expect it to satisfy requirements of Container, be usable with algorithms, range-based for, etc... The interface should similar too, there are many odd names in your case.
    $endgroup$
    – Dan Mašek
    Jun 20 at 23:44










  • $begingroup$
    It also has no Allocator.
    $endgroup$
    – rubenvb
    Jun 21 at 8:43










  • $begingroup$
    A good read for sobody implementing the vector. I wrote four articles on how to do it. Vector - Resource Management Allocation Vector - Resource Management Copy Swap Vector - Resize Vector - Simple Optimizations
    $endgroup$
    – Martin York
    10 hours ago
















  • $begingroup$
    STL-like? Some parts of it are somewhat similar to a specific instantiation (std::vector<int>), but there are more differences.
    $endgroup$
    – Deduplicator
    Jun 20 at 17:52






  • 3




    $begingroup$
    If it's meant to be STL-like, I'd at least expect it to satisfy requirements of Container, be usable with algorithms, range-based for, etc... The interface should similar too, there are many odd names in your case.
    $endgroup$
    – Dan Mašek
    Jun 20 at 23:44










  • $begingroup$
    It also has no Allocator.
    $endgroup$
    – rubenvb
    Jun 21 at 8:43










  • $begingroup$
    A good read for sobody implementing the vector. I wrote four articles on how to do it. Vector - Resource Management Allocation Vector - Resource Management Copy Swap Vector - Resize Vector - Simple Optimizations
    $endgroup$
    – Martin York
    10 hours ago















$begingroup$
STL-like? Some parts of it are somewhat similar to a specific instantiation (std::vector<int>), but there are more differences.
$endgroup$
– Deduplicator
Jun 20 at 17:52




$begingroup$
STL-like? Some parts of it are somewhat similar to a specific instantiation (std::vector<int>), but there are more differences.
$endgroup$
– Deduplicator
Jun 20 at 17:52




3




3




$begingroup$
If it's meant to be STL-like, I'd at least expect it to satisfy requirements of Container, be usable with algorithms, range-based for, etc... The interface should similar too, there are many odd names in your case.
$endgroup$
– Dan Mašek
Jun 20 at 23:44




$begingroup$
If it's meant to be STL-like, I'd at least expect it to satisfy requirements of Container, be usable with algorithms, range-based for, etc... The interface should similar too, there are many odd names in your case.
$endgroup$
– Dan Mašek
Jun 20 at 23:44












$begingroup$
It also has no Allocator.
$endgroup$
– rubenvb
Jun 21 at 8:43




$begingroup$
It also has no Allocator.
$endgroup$
– rubenvb
Jun 21 at 8:43












$begingroup$
A good read for sobody implementing the vector. I wrote four articles on how to do it. Vector - Resource Management Allocation Vector - Resource Management Copy Swap Vector - Resize Vector - Simple Optimizations
$endgroup$
– Martin York
10 hours ago




$begingroup$
A good read for sobody implementing the vector. I wrote four articles on how to do it. Vector - Resource Management Allocation Vector - Resource Management Copy Swap Vector - Resize Vector - Simple Optimizations
$endgroup$
– Martin York
10 hours ago










3 Answers
3






active

oldest

votes


















11












$begingroup$

Your two constructors don't store a value into m_capacity, so if the initial capacity requested (passed in as a parameter) is larger than the default capacity you'll have things in an inconsistent state and likely run into problems later.



Is there a reason you're not using std::make_unique<int[]>, instead of allocating memory with new and constructing a unique_ptr from it?



at member functions in the standard containers will perform bounds checking. Your at does not.



Is there a particular reason you're exiting the program if you detect a problem, rather than throwing an exception?



DetermineCapacity can enter an infinite loop if the actual_capacity *= GROWTH_FACTOR calculation overflows.



IncreaseCapacity and DecreaseCapacity are almost identical. Their functionality can be placed into a common function to avoid the code duplication.



You don't need to use this-> in member functions like capacity and size.



In pop, you need to read the value to return before you shrink the array. Since your resizing can reallocate memory and copy the vector contents, this can result in your reading an invalid value.



Why is insert always doing a reallocation?



Delete does not validate its argument, which can lead to Undefined Behavior.






share|improve this answer









$endgroup$




















    8












    $begingroup$

    Several of the public member names differ needlessly from those of the standard containers. That can prevent use of this class in generic code.



    For instance,




    void push(int);
    int pop();
    void prepend(int);
    bool isEmpty();



    I would have expected:



    void push_back(int);
    void pop_back();
    void push_front(int);
    bool empty() const;


    These ones, dealing with size and capacity, should normally use std::size_t rather than int:




    int size() const;
    int capacity() const;
    void resize(int);



    It's also worth providing the standard type definitions that generic code expects of a container (value_type, size_type, etc).



    We really, really need iterators for the collection. Then we wouldn't need find() to be a member, because std::find() does that job. insert() and erase() also normally accept iterators rather than indices.



    There's lots of unnecessary loops where standard algorithms could and should be used (std::fill() and std::move() in particular).



    I don't see why capacity calculation needs a loop. Just add the headroom to the required capacity rather than iterating over a fixed sequence of sizes.



    Libraries shouldn't write, especially to standard output (std::cerr is the appropriate place for error messages), and certainly shouldn't terminate the process (except perhaps if specifically built for debugging, with NDEBUG undefined).






    share|improve this answer









    $endgroup$




















      3












      $begingroup$

      static const int MIN_CAPACITY = 16;
      static const int GROWTH_FACTOR = 2;
      static const int SHRINK_FACTOR = 4;


      Global const variables automatically get internal linkage, thus making the statics redundant.



      Since you tagged your question c++11, the preferred way is to use constexpr variables:



      constexpr int MIN_CAPACITY = 16;
      constexpr int GROWTH_FACTOR = 2;
      constexpr int SHRINK_FACTOR = 4;


      Also, all-capital words are usually for macros.






      share|improve this answer









      $endgroup$















        Your Answer






        StackExchange.ifUsing("editor", function ()
        StackExchange.using("externalEditor", function ()
        StackExchange.using("snippets", function ()
        StackExchange.snippets.init();
        );
        );
        , "code-snippets");

        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "196"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );













        draft saved

        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222610%2fa-stl-like-vector-implementation-in-c%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        11












        $begingroup$

        Your two constructors don't store a value into m_capacity, so if the initial capacity requested (passed in as a parameter) is larger than the default capacity you'll have things in an inconsistent state and likely run into problems later.



        Is there a reason you're not using std::make_unique<int[]>, instead of allocating memory with new and constructing a unique_ptr from it?



        at member functions in the standard containers will perform bounds checking. Your at does not.



        Is there a particular reason you're exiting the program if you detect a problem, rather than throwing an exception?



        DetermineCapacity can enter an infinite loop if the actual_capacity *= GROWTH_FACTOR calculation overflows.



        IncreaseCapacity and DecreaseCapacity are almost identical. Their functionality can be placed into a common function to avoid the code duplication.



        You don't need to use this-> in member functions like capacity and size.



        In pop, you need to read the value to return before you shrink the array. Since your resizing can reallocate memory and copy the vector contents, this can result in your reading an invalid value.



        Why is insert always doing a reallocation?



        Delete does not validate its argument, which can lead to Undefined Behavior.






        share|improve this answer









        $endgroup$

















          11












          $begingroup$

          Your two constructors don't store a value into m_capacity, so if the initial capacity requested (passed in as a parameter) is larger than the default capacity you'll have things in an inconsistent state and likely run into problems later.



          Is there a reason you're not using std::make_unique<int[]>, instead of allocating memory with new and constructing a unique_ptr from it?



          at member functions in the standard containers will perform bounds checking. Your at does not.



          Is there a particular reason you're exiting the program if you detect a problem, rather than throwing an exception?



          DetermineCapacity can enter an infinite loop if the actual_capacity *= GROWTH_FACTOR calculation overflows.



          IncreaseCapacity and DecreaseCapacity are almost identical. Their functionality can be placed into a common function to avoid the code duplication.



          You don't need to use this-> in member functions like capacity and size.



          In pop, you need to read the value to return before you shrink the array. Since your resizing can reallocate memory and copy the vector contents, this can result in your reading an invalid value.



          Why is insert always doing a reallocation?



          Delete does not validate its argument, which can lead to Undefined Behavior.






          share|improve this answer









          $endgroup$















            11












            11








            11





            $begingroup$

            Your two constructors don't store a value into m_capacity, so if the initial capacity requested (passed in as a parameter) is larger than the default capacity you'll have things in an inconsistent state and likely run into problems later.



            Is there a reason you're not using std::make_unique<int[]>, instead of allocating memory with new and constructing a unique_ptr from it?



            at member functions in the standard containers will perform bounds checking. Your at does not.



            Is there a particular reason you're exiting the program if you detect a problem, rather than throwing an exception?



            DetermineCapacity can enter an infinite loop if the actual_capacity *= GROWTH_FACTOR calculation overflows.



            IncreaseCapacity and DecreaseCapacity are almost identical. Their functionality can be placed into a common function to avoid the code duplication.



            You don't need to use this-> in member functions like capacity and size.



            In pop, you need to read the value to return before you shrink the array. Since your resizing can reallocate memory and copy the vector contents, this can result in your reading an invalid value.



            Why is insert always doing a reallocation?



            Delete does not validate its argument, which can lead to Undefined Behavior.






            share|improve this answer









            $endgroup$



            Your two constructors don't store a value into m_capacity, so if the initial capacity requested (passed in as a parameter) is larger than the default capacity you'll have things in an inconsistent state and likely run into problems later.



            Is there a reason you're not using std::make_unique<int[]>, instead of allocating memory with new and constructing a unique_ptr from it?



            at member functions in the standard containers will perform bounds checking. Your at does not.



            Is there a particular reason you're exiting the program if you detect a problem, rather than throwing an exception?



            DetermineCapacity can enter an infinite loop if the actual_capacity *= GROWTH_FACTOR calculation overflows.



            IncreaseCapacity and DecreaseCapacity are almost identical. Their functionality can be placed into a common function to avoid the code duplication.



            You don't need to use this-> in member functions like capacity and size.



            In pop, you need to read the value to return before you shrink the array. Since your resizing can reallocate memory and copy the vector contents, this can result in your reading an invalid value.



            Why is insert always doing a reallocation?



            Delete does not validate its argument, which can lead to Undefined Behavior.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jun 20 at 0:57









            1201ProgramAlarm1201ProgramAlarm

            4,2382 gold badges11 silver badges27 bronze badges




            4,2382 gold badges11 silver badges27 bronze badges























                8












                $begingroup$

                Several of the public member names differ needlessly from those of the standard containers. That can prevent use of this class in generic code.



                For instance,




                void push(int);
                int pop();
                void prepend(int);
                bool isEmpty();



                I would have expected:



                void push_back(int);
                void pop_back();
                void push_front(int);
                bool empty() const;


                These ones, dealing with size and capacity, should normally use std::size_t rather than int:




                int size() const;
                int capacity() const;
                void resize(int);



                It's also worth providing the standard type definitions that generic code expects of a container (value_type, size_type, etc).



                We really, really need iterators for the collection. Then we wouldn't need find() to be a member, because std::find() does that job. insert() and erase() also normally accept iterators rather than indices.



                There's lots of unnecessary loops where standard algorithms could and should be used (std::fill() and std::move() in particular).



                I don't see why capacity calculation needs a loop. Just add the headroom to the required capacity rather than iterating over a fixed sequence of sizes.



                Libraries shouldn't write, especially to standard output (std::cerr is the appropriate place for error messages), and certainly shouldn't terminate the process (except perhaps if specifically built for debugging, with NDEBUG undefined).






                share|improve this answer









                $endgroup$

















                  8












                  $begingroup$

                  Several of the public member names differ needlessly from those of the standard containers. That can prevent use of this class in generic code.



                  For instance,




                  void push(int);
                  int pop();
                  void prepend(int);
                  bool isEmpty();



                  I would have expected:



                  void push_back(int);
                  void pop_back();
                  void push_front(int);
                  bool empty() const;


                  These ones, dealing with size and capacity, should normally use std::size_t rather than int:




                  int size() const;
                  int capacity() const;
                  void resize(int);



                  It's also worth providing the standard type definitions that generic code expects of a container (value_type, size_type, etc).



                  We really, really need iterators for the collection. Then we wouldn't need find() to be a member, because std::find() does that job. insert() and erase() also normally accept iterators rather than indices.



                  There's lots of unnecessary loops where standard algorithms could and should be used (std::fill() and std::move() in particular).



                  I don't see why capacity calculation needs a loop. Just add the headroom to the required capacity rather than iterating over a fixed sequence of sizes.



                  Libraries shouldn't write, especially to standard output (std::cerr is the appropriate place for error messages), and certainly shouldn't terminate the process (except perhaps if specifically built for debugging, with NDEBUG undefined).






                  share|improve this answer









                  $endgroup$















                    8












                    8








                    8





                    $begingroup$

                    Several of the public member names differ needlessly from those of the standard containers. That can prevent use of this class in generic code.



                    For instance,




                    void push(int);
                    int pop();
                    void prepend(int);
                    bool isEmpty();



                    I would have expected:



                    void push_back(int);
                    void pop_back();
                    void push_front(int);
                    bool empty() const;


                    These ones, dealing with size and capacity, should normally use std::size_t rather than int:




                    int size() const;
                    int capacity() const;
                    void resize(int);



                    It's also worth providing the standard type definitions that generic code expects of a container (value_type, size_type, etc).



                    We really, really need iterators for the collection. Then we wouldn't need find() to be a member, because std::find() does that job. insert() and erase() also normally accept iterators rather than indices.



                    There's lots of unnecessary loops where standard algorithms could and should be used (std::fill() and std::move() in particular).



                    I don't see why capacity calculation needs a loop. Just add the headroom to the required capacity rather than iterating over a fixed sequence of sizes.



                    Libraries shouldn't write, especially to standard output (std::cerr is the appropriate place for error messages), and certainly shouldn't terminate the process (except perhaps if specifically built for debugging, with NDEBUG undefined).






                    share|improve this answer









                    $endgroup$



                    Several of the public member names differ needlessly from those of the standard containers. That can prevent use of this class in generic code.



                    For instance,




                    void push(int);
                    int pop();
                    void prepend(int);
                    bool isEmpty();



                    I would have expected:



                    void push_back(int);
                    void pop_back();
                    void push_front(int);
                    bool empty() const;


                    These ones, dealing with size and capacity, should normally use std::size_t rather than int:




                    int size() const;
                    int capacity() const;
                    void resize(int);



                    It's also worth providing the standard type definitions that generic code expects of a container (value_type, size_type, etc).



                    We really, really need iterators for the collection. Then we wouldn't need find() to be a member, because std::find() does that job. insert() and erase() also normally accept iterators rather than indices.



                    There's lots of unnecessary loops where standard algorithms could and should be used (std::fill() and std::move() in particular).



                    I don't see why capacity calculation needs a loop. Just add the headroom to the required capacity rather than iterating over a fixed sequence of sizes.



                    Libraries shouldn't write, especially to standard output (std::cerr is the appropriate place for error messages), and certainly shouldn't terminate the process (except perhaps if specifically built for debugging, with NDEBUG undefined).







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jun 20 at 8:25









                    Toby SpeightToby Speight

                    30.3k7 gold badges45 silver badges132 bronze badges




                    30.3k7 gold badges45 silver badges132 bronze badges





















                        3












                        $begingroup$

                        static const int MIN_CAPACITY = 16;
                        static const int GROWTH_FACTOR = 2;
                        static const int SHRINK_FACTOR = 4;


                        Global const variables automatically get internal linkage, thus making the statics redundant.



                        Since you tagged your question c++11, the preferred way is to use constexpr variables:



                        constexpr int MIN_CAPACITY = 16;
                        constexpr int GROWTH_FACTOR = 2;
                        constexpr int SHRINK_FACTOR = 4;


                        Also, all-capital words are usually for macros.






                        share|improve this answer









                        $endgroup$

















                          3












                          $begingroup$

                          static const int MIN_CAPACITY = 16;
                          static const int GROWTH_FACTOR = 2;
                          static const int SHRINK_FACTOR = 4;


                          Global const variables automatically get internal linkage, thus making the statics redundant.



                          Since you tagged your question c++11, the preferred way is to use constexpr variables:



                          constexpr int MIN_CAPACITY = 16;
                          constexpr int GROWTH_FACTOR = 2;
                          constexpr int SHRINK_FACTOR = 4;


                          Also, all-capital words are usually for macros.






                          share|improve this answer









                          $endgroup$















                            3












                            3








                            3





                            $begingroup$

                            static const int MIN_CAPACITY = 16;
                            static const int GROWTH_FACTOR = 2;
                            static const int SHRINK_FACTOR = 4;


                            Global const variables automatically get internal linkage, thus making the statics redundant.



                            Since you tagged your question c++11, the preferred way is to use constexpr variables:



                            constexpr int MIN_CAPACITY = 16;
                            constexpr int GROWTH_FACTOR = 2;
                            constexpr int SHRINK_FACTOR = 4;


                            Also, all-capital words are usually for macros.






                            share|improve this answer









                            $endgroup$



                            static const int MIN_CAPACITY = 16;
                            static const int GROWTH_FACTOR = 2;
                            static const int SHRINK_FACTOR = 4;


                            Global const variables automatically get internal linkage, thus making the statics redundant.



                            Since you tagged your question c++11, the preferred way is to use constexpr variables:



                            constexpr int MIN_CAPACITY = 16;
                            constexpr int GROWTH_FACTOR = 2;
                            constexpr int SHRINK_FACTOR = 4;


                            Also, all-capital words are usually for macros.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jun 20 at 9:27









                            L. F.L. F.

                            1,0294 silver badges21 bronze badges




                            1,0294 silver badges21 bronze badges



























                                draft saved

                                draft discarded
















































                                Thanks for contributing an answer to Code Review Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid


                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.

                                Use MathJax to format equations. MathJax reference.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222610%2fa-stl-like-vector-implementation-in-c%23new-answer', 'question_page');

                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

                                Circuit construction for execution of conditional statements using least significant bitHow are two different registers being used as “control”?How exactly is the stated composite state of the two registers being produced using the $R_zz$ controlled rotations?Efficiently performing controlled rotations in HHLWould this quantum algorithm implementation work?How to prepare a superposed states of odd integers from $1$ to $sqrtN$?Why is this implementation of the order finding algorithm not working?Circuit construction for Hamiltonian simulationHow can I invert the least significant bit of a certain term of a superposed state?Implementing an oracleImplementing a controlled sum operation

                                Magento 2 “No Payment Methods” in Admin New OrderHow to integrate Paypal Express Checkout with the Magento APIMagento 1.5 - Sales > Order > edit order and shipping methods disappearAuto Invoice Check/Money Order Payment methodAdd more simple payment methods?Shipping methods not showingWhat should I do to change payment methods if changing the configuration has no effects?1.9 - No Payment Methods showing upMy Payment Methods not Showing for downloadable/virtual product when checkout?Magento2 API to access internal payment methodHow to call an existing payment methods in the registration form?