Skip to content

Instantly share code, notes, and snippets.

@grayed
Last active March 27, 2021 14:57
Show Gist options
  • Save grayed/c059bbf1ad9326102a339f49f2e3050c to your computer and use it in GitHub Desktop.
Save grayed/c059bbf1ad9326102a339f49f2e3050c to your computer and use it in GitHub Desktop.
// https://gist.github.com/grayed
// Application Programming Interface (API)
#include <iostream>
#include <exception>
template<typename T>
class MyArray {
struct MyArrayData {
MyArrayData(size_t sz_) : p(new T[sz_]), sz(sz_), allocated(sz_), refcnt(1) { }
MyArrayData(T* p_, size_t sz_) : p(p_), sz(sz_), allocated(sz_), refcnt(1) {}
~MyArrayData() { delete[] p; }
T* p;
size_t sz, allocated, refcnt;
} *d;
public:
MyArray(size_t sz_ = 0) : d(new MyArrayData(sz_)) { }
MyArray(const MyArray<T>& other) : d(other.d) {
d->refcnt++;
}
// 1. Освобождение памяти
~MyArray() {
if (--d->refcnt == 0)
delete d;
}
// 2. Сложение массивов
MyArray<T> operator +(const MyArray<T>& other) const {
MyArray<T> result(d->sz + other.d->sz);
for (size_t i = 0; i < d->sz; i++)
result.d->p[i] = d->p[i];
for (size_t i = 0; i < other.d->sz; i++)
result.d->p[d->sz + i] = other.d->p[i];
return result;
}
// 3. Доступ к элементам массива (с изменением массива и без оного)
T operator[] (size_t i) const {
if (i >= d->sz)
throw std::invalid_argument("invalid index");
return d->p[i];
}
T& operator[] (size_t i) {
if (i >= d->sz)
resize(i + 1);
return d->p[i];
}
size_t getSize() const { return d->sz; }
void resize(size_t newSize) {
if (newSize <= d->allocated && d->refcnt == 1) {
d->sz = newSize;
return;
}
std::cerr << "reallocating from " << d->allocated << " to " << newSize << std::endl;
// создать новый T[newSize]
auto newp = new T[newSize];
// скопировать нужное количество элементов из p
for (size_t i = 0; i < d->sz; i++)
newp[i] = d->p[i];
// освободить p
if (d->refcnt == 1) {
delete[] d->p;
d->p = newp;
d->sz = newSize;
d->allocated = newSize;
} else {
MyArrayData* newData = new MyArrayData(newp, newSize);
d->refcnt--;
d = newData;
}
}
};
int main(int argc, char** argv) {
MyArray<int> arr1(123), arr2(33);
MyArray<int> foo = arr1;
arr1[12] = arr2[42];
MyArray<int> arr3 = arr1 + arr2;
const MyArray<int>& aref = arr3;
MyArray<int>& aref2 = arr3;
aref2[3] = 3;
std::cout << "Result size: " << arr3.getSize() << std::endl;
aref2.resize(100);
std::cout << "Changed size: " << aref2.getSize() << std::endl;
aref2.resize(200);
std::cout << "Changed second time size: " << aref2.getSize() << std::endl;
std::cout << "First Element: " << aref[0] << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment