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;
$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.
c++ c++11 vectors
$endgroup$
add a comment |
$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.
c++ c++11 vectors
$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
add a comment |
$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.
c++ c++11 vectors
$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
c++ c++11 vectors
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
add a comment |
$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
add a comment |
3 Answers
3
active
oldest
votes
$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.
$endgroup$
add a comment |
$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).
$endgroup$
add a comment |
$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 static
s 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.
$endgroup$
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$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.
$endgroup$
add a comment |
$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.
$endgroup$
add a comment |
$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.
$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.
answered Jun 20 at 0:57
1201ProgramAlarm1201ProgramAlarm
4,2382 gold badges11 silver badges27 bronze badges
4,2382 gold badges11 silver badges27 bronze badges
add a comment |
add a comment |
$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).
$endgroup$
add a comment |
$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).
$endgroup$
add a comment |
$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).
$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).
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
add a comment |
add a comment |
$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 static
s 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.
$endgroup$
add a comment |
$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 static
s 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.
$endgroup$
add a comment |
$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 static
s 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.
$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 static
s 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.
answered Jun 20 at 9:27
L. F.L. F.
1,0294 silver badges21 bronze badges
1,0294 silver badges21 bronze badges
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
$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