Skip to main content
Code Review

Return to Question

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
  1. My ArrayList class guarantees strong exception safety, using the copy and swap idiom copy and swap idiom
  2. The container still works if T passed in is not default-constructible
  3. Correctness of the implementation of the Rule of Five Rule of Five
  4. General correctness and efficiency (i.e: No memory leaks, dangling pointers, etc.)
  1. My ArrayList class guarantees strong exception safety, using the copy and swap idiom
  2. The container still works if T passed in is not default-constructible
  3. Correctness of the implementation of the Rule of Five
  4. General correctness and efficiency (i.e: No memory leaks, dangling pointers, etc.)
  1. My ArrayList class guarantees strong exception safety, using the copy and swap idiom
  2. The container still works if T passed in is not default-constructible
  3. Correctness of the implementation of the Rule of Five
  4. General correctness and efficiency (i.e: No memory leaks, dangling pointers, etc.)
added 8 characters in body; edited title
Source Link
Jamal
  • 35.2k
  • 13
  • 134
  • 238

Simplified Implementationimplementation of vectorstd::vector in C++

I implemented a simplified version of a C++ vectorstd::vector/ArrayListArrayList learning from this link. From it, I tried to write an ArrayListArrayList class rather than a Vector. In my ArrayListArrayList implementation, I didn't add iterators, operator[]operator[], emplace and a lot of other stuff because my main focus is to practice the following aspects:

  1. My ArrayListArrayList class guranteesguarantees Strong Exception Safetystrong exception safety, using the copy and swap idiom
  2. The container still works if TT passed in is not default constructible-constructible
  3. Correctness of the implementation of the Rule of Five
  4. General correctness and efficiency (i.e: No memory leaks, dangling pointers ... .., etc.)

Please focus on those 4 areas I mentioned for reviewing my code, and any other important style choice errors or any other problems that I missed.

Thanks

Simplified Implementation of vector in C++

I implemented a simplified version of a C++ vector/ArrayList learning from this link. From it, I tried to write an ArrayList class rather than a Vector. In my ArrayList implementation, I didn't add iterators, operator[], emplace and a lot of other stuff because my main focus is to practice the following aspects:

  1. My ArrayList class gurantees Strong Exception Safety, using the copy and swap idiom
  2. The container still works if T passed in is not default constructible
  3. Correctness of the implementation of the Rule of Five
  4. General correctness and efficiency (i.e: No memory leaks, dangling pointers ... ...)

Please focus on those 4 areas I mentioned for reviewing my code, and any other important style choice errors or any other problems that I missed.

Thanks

Simplified implementation of std::vector in C++

I implemented a simplified version of a C++ std::vector/ArrayList learning from this link. From it, I tried to write an ArrayList class rather than a Vector. In my ArrayList implementation, I didn't add iterators, operator[], emplace and a lot of other stuff because my main focus is to practice the following aspects:

  1. My ArrayList class guarantees strong exception safety, using the copy and swap idiom
  2. The container still works if T passed in is not default-constructible
  3. Correctness of the implementation of the Rule of Five
  4. General correctness and efficiency (i.e: No memory leaks, dangling pointers, etc.)

Please focus on those 4 areas I mentioned for reviewing my code, and any other important style choice errors or any other problems that I missed.

Rollback to Revision 1
Source Link
200_success
  • 145.6k
  • 22
  • 190
  • 479
using namespace std;
template <typename T>
class ArrayList
{
 public:
 ArrayList();
 ArrayList(int size);
 ArrayList(const ArrayList<T>& other);
 ArrayList(ArrayList&& other);
 ~ArrayList();
 ArrayList<T>& operator= (const ArrayList<T>& other);
 ArrayList<T>& operator= (ArrayList&& other);
 void add(const T& item);
 void add(T&& item);
 void remove(int index);
 friend void swap(ArrayList& A, ArrayList& B)
 {
 using std::swap;
 swap(A.actualSize, B.actualSize);
 swap(A.allocatedSize, B.allocatedSize);
 swap(A.arr, B.arr);
 }
 private:
 T* arr;
 size_t allocatedSize;
 size_t actualSize;
 
 void resize();
 void addInternal(const T& item);
 void addInternalMove(T&& item);
};
template <typename T>
ArrayList<T>::ArrayList()
{
 arr = static_cast<T*>(::operator new(sizeof(T)*100));
 actualSize = 0;
 allocatedSize = 100;
}
template <typename T>
ArrayList<T>::ArrayList(int size)
{
 if(size < 0)
 throw;
 arr = static_cast<T*>(::operator new(sizeof(T)*size));
 actualSize = 0;
 allocatedSize = size;
}
template <typename T>
ArrayList<T>::ArrayList(const ArrayList<T>& other)
{
 arr = static_cast<T*>(::operator new(sizeof(T)*size));
 allocatedSize = other.allocatedSize;
 actualSize = other.actualSize;
 for(size_t i = 0; i<other.actualSize; i++)
 add(other.arr[i]);
}
template <typename T>
ArrayList<T>::ArrayList(ArrayList&& other)
{
 swap(*this, other);
}
template <typename T>
ArrayList<T>::~ArrayList()
{
 for(size_t i = 0; i<actualSize; i++)
 {
 arr[i].~T();
 }::operator delete(arr);
}
template <typename T>
ArrayList& ArrayList<T>::operator =(const ArrayList<T>& other)
{
 ArrayList tmp(other);
 swap(*this, tmp);
 return *this;
}
template <typename T>
ArrayList& ArrayList<T>::operator =(ArrayList<T>&& other)
{
 swap(*this, other);
}
template <typename T>
void ArrayList<T>::resize()
{
 allocatedSize *= 2;
 ArrayList tmp(allocatedSize);
 for(size_t i=0; i<actualSize; i++)
 addInternal(arr[i]);
 swap(*this, tmp);
}
template <typename T>
void ArrayList<T>::add(const T& item)
{
 if(actualSize >= allocatedSize)
 resize();
 addInternal(item);
}
template <typename T>
void ArrayList<T>::add(T&& item)
{
 if(actualSize >= allocatedSize)
 resize();
 addInternalMove(move(item));
}
template <typename T>
void ArrayList<T>::addInternal(const T& item)
{
 new (arr+actualSize)T(item);
 actualSize++;
}
template <typename T>
void ArrayList<T>::addInternalMove(T&& item)
{
 new (arr+actualSize)T(move(item));
 actualSize++;
}
template <typename T>
void ArrayList<T>::remove(int index)
{
 if(index<0 || index>actualSize - 1)
 throw;
 for(size_t i=0; i<actualSize; i++)
 {
 if(index==i)
 {
 arr[i].~T();
 arr[i+1] = arr[i];
 }
 else if(index > i)
 arr[i+1] = arr[i];
 }
}
using namespace std;
template <typename T>
class ArrayList
{
 public:
 ArrayList();
 ArrayList(int size);
 ArrayList(const ArrayList<T>& other);
 ArrayList(ArrayList&& other);
 ~ArrayList();
 ArrayList<T>& operator= (const ArrayList<T>& other);
 ArrayList<T>& operator= (ArrayList&& other);
 void add(const T& item);
 void add(T&& item);
 void remove(int index);
 friend void swap(ArrayList& A, ArrayList& B)
 {
 using std::swap;
 swap(A.actualSize, B.actualSize);
 swap(A.allocatedSize, B.allocatedSize);
 swap(A.arr, B.arr);
 }
 private:
 T* arr;
 size_t allocatedSize;
 size_t actualSize;
 
 void resize();
 void addInternal(const T& item);
 void addInternalMove(T&& item);
};
template <typename T>
ArrayList<T>::ArrayList()
{
 arr = static_cast<T*>(::operator new(sizeof(T)*100));
 actualSize = 0;
 allocatedSize = 100;
}
template <typename T>
ArrayList<T>::ArrayList(int size)
{
 if(size < 0)
 throw;
 arr = static_cast<T*>(::operator new(sizeof(T)*size));
 actualSize = 0;
 allocatedSize = size;
}
template <typename T>
ArrayList<T>::ArrayList(const ArrayList<T>& other)
{
 arr = static_cast<T*>(::operator new(sizeof(T)*size));
 allocatedSize = other.allocatedSize;
 actualSize = other.actualSize;
 for(size_t i = 0; i<other.actualSize; i++)
 add(other.arr[i]);
}
template <typename T>
ArrayList<T>::ArrayList(ArrayList&& other)
{
 swap(*this, other);
}
template <typename T>
ArrayList<T>::~ArrayList()
{
 for(size_t i = 0; i<actualSize; i++)
 {
 arr[i].~T();
 }::operator delete(arr);
}
template <typename T>
ArrayList& ArrayList<T>::operator =(const ArrayList<T>& other)
{
 ArrayList tmp(other);
 swap(*this, tmp);
 return *this;
}
template <typename T>
ArrayList& ArrayList<T>::operator =(ArrayList<T>&& other)
{
 swap(*this, other);
}
template <typename T>
void ArrayList<T>::resize()
{
 allocatedSize *= 2;
 ArrayList tmp(allocatedSize);
 for(size_t i=0; i<actualSize; i++)
 addInternal(arr[i]);
 swap(*this, tmp);
}
template <typename T>
void ArrayList<T>::add(const T& item)
{
 if(actualSize >= allocatedSize)
 resize();
 addInternal(item);
}
template <typename T>
void ArrayList<T>::add(T&& item)
{
 if(actualSize >= allocatedSize)
 resize();
 addInternalMove(move(item));
}
template <typename T>
void ArrayList<T>::addInternal(const T& item)
{
 new (arr+actualSize)T(item);
 actualSize++;
}
template <typename T>
void ArrayList<T>::addInternalMove(T&& item)
{
 new (arr+actualSize)T(move(item));
 actualSize++;
}
template <typename T>
void ArrayList<T>::remove(int index)
{
 if(index<0 || index>actualSize - 1)
 throw;
 for(size_t i=0; i<actualSize; i++)
 {
 if(index==i)
 {
 arr[i].~T();
 arr[i+1] = arr[i];
 }
 else if(index > i)
 arr[i+1] = arr[i];
 }
}
using namespace std;
template <typename T>
class ArrayList
{
 public:
 ArrayList();
 ArrayList(int size);
 ArrayList(const ArrayList<T>& other);
 ArrayList(ArrayList&& other);
 ~ArrayList();
 ArrayList<T>& operator= (const ArrayList<T>& other);
 ArrayList<T>& operator= (ArrayList&& other);
 void add(const T& item);
 void add(T&& item);
 void remove(int index);
 friend void swap(ArrayList& A, ArrayList& B)
 {
 using std::swap;
 swap(A.actualSize, B.actualSize);
 swap(A.allocatedSize, B.allocatedSize);
 swap(A.arr, B.arr);
 }
 private:
 T* arr;
 size_t allocatedSize;
 size_t actualSize;
 
 void resize();
 void addInternal(const T& item);
 void addInternalMove(T&& item);
};
template <typename T>
ArrayList<T>::ArrayList()
{
 arr = static_cast<T*>(::operator new(sizeof(T)*100));
 actualSize = 0;
 allocatedSize = 100;
}
template <typename T>
ArrayList<T>::ArrayList(int size)
{
 if(size < 0)
 throw;
 arr = static_cast<T*>(::operator new(sizeof(T)*size));
 actualSize = 0;
 allocatedSize = size;
}
template <typename T>
ArrayList<T>::ArrayList(const ArrayList<T>& other)
{
 arr = static_cast<T*>(::operator new(sizeof(T)*size));
 allocatedSize = other.allocatedSize;
 actualSize = actualSize;
 for(size_t i = 0; i<other.actualSize; i++)
 add(other.arr[i]);
}
template <typename T>
ArrayList<T>::ArrayList(ArrayList&& other)
{
 swap(*this, other);
}
template <typename T>
ArrayList<T>::~ArrayList()
{
 for(size_t i = 0; i<actualSize; i++)
 {
 arr[i].~T();
 }::operator delete(arr);
}
template <typename T>
ArrayList& ArrayList<T>::operator =(const ArrayList<T>& other)
{
 ArrayList tmp(other);
 swap(*this, tmp);
 return *this;
}
template <typename T>
ArrayList& ArrayList<T>::operator =(ArrayList<T>&& other)
{
 swap(*this, other);
}
template <typename T>
void ArrayList<T>::resize()
{
 allocatedSize *= 2;
 ArrayList tmp(allocatedSize);
 for(size_t i=0; i<actualSize; i++)
 addInternal(arr[i]);
 swap(*this, tmp);
}
template <typename T>
void ArrayList<T>::add(const T& item)
{
 if(actualSize >= allocatedSize)
 resize();
 addInternal(item);
}
template <typename T>
void ArrayList<T>::add(T&& item)
{
 if(actualSize >= allocatedSize)
 resize();
 addInternalMove(move(item));
}
template <typename T>
void ArrayList<T>::addInternal(const T& item)
{
 new (arr+actualSize)T(item);
 actualSize++;
}
template <typename T>
void ArrayList<T>::addInternalMove(T&& item)
{
 new (arr+actualSize)T(move(item));
 actualSize++;
}
template <typename T>
void ArrayList<T>::remove(int index)
{
 if(index<0 || index>actualSize - 1)
 throw;
 for(size_t i=0; i<actualSize; i++)
 {
 if(index==i)
 {
 arr[i].~T();
 arr[i+1] = arr[i];
 }
 else if(index > i)
 arr[i+1] = arr[i];
 }
}
Missed a syntax error assigning actualSize = actualSize
Source Link
Mantracker
  • 305
  • 2
  • 9
Loading
Source Link
Mantracker
  • 305
  • 2
  • 9
Loading
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /