Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

The homework is creating own my smart_ptr() class. I want to pass from case7 to case 13. count of number of refernce cause failing from

The homework is creating own my smart_ptr() class. I want to pass from case7 to case 13. count of number of refernce cause failing from case 7 to cas 13

1. Don't use shared ptr, unique ptr and weak ptr. 2. Don't fix anything below ourtype struct.

Below the ourtype is source code to evaluate my source code, so you can only fix the source code above ourtype.

#include

#include

#include

#include

using namespace std;

class null_ptr_exception : public runtime_error

{

public:

null_ptr_exception(const char* msg): runtime_error(msg)

{

}

private:

char* msg;

};

template

class smart_ptr

{

private:

T* ptr_; // pointer to the referred object

int* ref_; // pointer to a reference count

virtual smart_ptr * some_impl() const

{

return new smart_ptr(*this) ;

}

public:

smart_ptr() noexcept :ptr_(nullptr), ref_(nullptr)

{

}

// Create a smart_ptr that is initialized to NULL. The reference count

// should be zero.

explicit smart_ptr(T* raw_ptr)

{

T* temp ;

temp = new T(*raw_ptr);

ref_ = new int(1);

delete raw_ptr;

raw_ptr= temp;

}

// Create a smart_ptr that is initialized to raw_ptr. The reference count

// should be one.

smart_ptr(const smart_ptr& rhs) noexcept

{

ptr_=rhs.ptr_;

ref_=rhs.ref_;

(*ref_)++;

}

// Copy construct a pointer from rhs. The reference count should be

// incremented by one.

smart_ptr(smart_ptr&& rhs) noexcept

{

ptr_ = nullptr;

ref_ = 0;

// Copy the datas from the source object.

ptr_ = rhs.ptr_;

ref_ = rhs.ref_;

// Release the pointer from the source object so that the destructor does not free the memory multiple times.

rhs.ptr_ = nullptr;

rhs.ref_ = 0;

}

// Move construct a pointer from rhs.

smart_ptr& operator=(const smart_ptr& rhs) noexcept

{

if (this != &rhs) // Avoid self assignment

{

// if reference become zero, delete the ptr & ref

if(ref_ == nullptr || ref_==0)

{

delete (ptr_);

delete (ref_);

}

// Copy the data and reference pointer

ptr_ = rhs.ptr_;

ref_ = rhs.ref_;

if(ref_ == NULL )

{

delete ptr_;

delete ref_;

}

else

++(*ref_);

}

return *this;

}

// This assignment should make a shallow copy of the right-hand side's

// pointer data. The reference count should be incremented as appropriate.

smart_ptr& operator=(smart_ptr&& rhs)noexcept

{

int* temp_ref = nullptr;

T* temp_ptr = nullptr;

if (rhs.ref_)

{

temp_ref = new int(*rhs.ref_);

temp_ptr = new T (*rhs.ptr_);

}

delete ref_;

delete ptr_;

ptr_ = temp_ptr;

ref_ = temp_ref;

return *this;

}

// This move assignment should steal the right-hand side's pointer data.

bool clone()

{

bool result =false;

T* temp;

if(ref_ != nullptr || ptr_ != nullptr)

{

--(*ref_);

ptr_ = new T(*ptr_);

ref_ =new int(1);

return true;

}

else

return result;

}

// If the smart_ptr is either NULL or has a reference count of one, this

// function will do nothing and return false. Otherwise, the referred to

// object's reference count will be decreased and a new deep copy of the

// object will be created. This new copy will be the object that this

// smart_ptr points and its reference count will be one.

int ref_count() const noexcept

{

if(ref_ != nullptr)

return *ref_;

else

return 0;

}

// Returns the reference count of the pointed to data.

T& operator*()

{

if(ptr_!=nullptr)

{

return (*ptr_);

}

else

throw null_ptr_exception("Invalid this ptr");

}

// The dereference operator shall return a reference to the referred object.

// Throws null_ptr_exception on invalid access.

T* operator->()

{

if(ptr_!=nullptr)

{

return (ptr_);

}

else

throw null_ptr_exception("Invalid this ptr");

}

// The arrow operator shall return the pointer ptr_. Throws null_ptr_exception

// on invalid access.

~smart_ptr()

{

if(ref_ == nullptr)

{

delete ptr_;

delete ref_;

}

else if((*ref_) > 1)

{

--(*ref_);

}

else if((*ref_) <=1)

{

delete ref_;

}

} // deallocate all dynamic memory

};

/*

void g()

{

throw std::exception();

}

void f()

{

int* pI = new int(2);

*pI = 3;

g();

// Oops, if an exception is thrown, pI is never deleted

// and we have a memory leak

delete pI;

}

int main()

{

try

{

f();

}

catch(...)

{ }

return 0;

}

*/

#include

#include

#include

#include

struct OurType

{

explicit OurType(int v = 0) : m_value(v) { m_count++; }

OurType(const OurType& other) : m_value(other.m_value)

{ m_count++; m_asstcopycount++; }

~OurType() { m_count--; }

OurType& operator=(const OurType& rhs)

{ m_value = rhs.m_value; m_asstcopycount++; return *this; }

int m_value;

static int m_count;

static int m_asstcopycount;

};

inline

bool operator==(const OurType& lhs, const OurType& rhs)

{ return lhs.m_value == rhs.m_value; }

inline

bool operator<(const OurType& lhs, const OurType& rhs)

{ return lhs.m_value < rhs.m_value; }

inline

bool operator!=(const OurType& lhs, const OurType& rhs)

{ return ! (lhs == rhs); }

inline

bool operator<=(const OurType& lhs, const OurType& rhs)

{ return ! (rhs < lhs); }

inline

bool operator>=(const OurType& lhs, const OurType& rhs)

{ return ! (lhs < rhs); }

inline

bool operator>(const OurType& lhs, const OurType& rhs)

{ return rhs < lhs; }

inline

bool operator==(const OurType& lhs, int rhs)

{ return lhs.m_value == rhs; }

inline

bool operator!=(const OurType& lhs, int rhs)

{ return ! (lhs == rhs); }

#include

inline

std::ostream& operator<<(std::ostream& lhs, const OurType& rhs)

{ return lhs << rhs.m_value; }

int OurType::m_count = 0;

int OurType::m_asstcopycount = 0;

inline int itemcount()

{

return OurType::m_count;

}

inline int nasstcopys()

{

return OurType::m_asstcopycount;

}

std::set addrs;

bool recordaddrs = false;

int throwBadAlloc = 0;

// value of 0 means allocations don't throw

// value of 1 means 1st allocation throws

// value of 2 means 2nd allocation throws

// value of n means nth allocation throws

void* operator new(size_t n)

{

if (recordaddrs) {

if (throwBadAlloc == 1)

throw std::bad_alloc();

else if(throwBadAlloc > 1)

throwBadAlloc--;

}

void* p = malloc(n);

if (recordaddrs)

{

recordaddrs = false;

addrs.insert(p);

recordaddrs = true;

}

return p;

}

void operator delete(void* p) noexcept

{

if (recordaddrs)

{

recordaddrs = false;

std::set::iterator it = addrs.find(p);

if (it != addrs.end())

addrs.erase(it);

recordaddrs = true;

}

free(p);

}

void testone(int n)

{

smart_ptr dsp0;

smart_ptr dsp1 {new double {3.14}};

smart_ptr dsp2, dsp3;

switch (n)

{

default: {

assert(false);

} break; case 1: {

assert(dsp0.ref_count() == 0);

} break; case 2: {

assert(dsp1.ref_count() == 1);

} break; case 3: {

dsp0 = dsp1;

assert(dsp0.ref_count() == 2);

} break; case 4: {

dsp3 = dsp2 = dsp1;

assert(dsp3.ref_count() == dsp2.ref_count() &&

dsp1.ref_count() == dsp2.ref_count() &&

dsp1.ref_count() == 3);

} break; case 5: {

dsp1 = dsp0;

assert(dsp1.ref_count() == 0 && dsp2.ref_count() == 0);

} break; case 6: {

assert(std::is_nothrow_constructible>::value);

assert(std::is_nothrow_copy_constructible>::value);

// possible XCode compiler bug for following two asserts

//assert(std::is_nothrow_constructible,int*>::value);

//assert(std::is_nothrow_assignable::value);

assert(std::is_nothrow_move_assignable>::value);

assert(std::is_nothrow_move_constructible>::value);

assert(!noexcept(std::declval>().clone()));

assert(!noexcept(std::declval>().operator*()));

assert(!noexcept(std::declval>().operator->()));

assert(noexcept(std::declval>().ref_count()));

} break; case 7: {

{

// testing constructor

smart_ptr osp0 {new OurType{0}};

assert(itemcount() == 1);

}

cout << itemcount();

assert(itemcount() == 0);

} break; case 8: {

{

// testing assignment operator

smart_ptr osp0 {new OurType{0}};

assert(itemcount() == 1);

smart_ptr osp1;

osp1 = osp0;

assert(itemcount() == 1);

}

assert(itemcount() == 0);

} break; case 9: {

{

// testing copy constructor

smart_ptr osp0 {new OurType{0}};

assert(itemcount() == 1);

smart_ptr osp1{osp0};

assert(osp0.ref_count() == 2);

assert(osp1.ref_count() == 2);

assert(itemcount() == 1);

}

assert(itemcount() == 0);

} break; case 10: {

{

// testing move constructor

smart_ptr osp0 {new OurType{0}};

assert(itemcount() == 1);

smart_ptr osp1{std::move(osp0)};

assert(itemcount() == 1);

}

assert(itemcount() == 0);

} break; case 11: {

{

// testing move assignment

smart_ptr osp0 {new OurType{0}};

assert(osp0.ref_count() == 1);

assert(itemcount() == 1);

smart_ptr osp1;

osp1 = std::move(osp0);

assert(osp1.ref_count() == 1);

assert(osp0.ref_count() == 0);

assert(itemcount() == 1);

}

assert(itemcount() == 0);

} break; case 12: {

{

// testing move constructor

smart_ptr osp0 {new OurType{0}};

assert(osp0.ref_count() == 1);

assert(itemcount() == 1);

smart_ptr osp1{std::move(osp0)};

assert(osp1.ref_count() == 1);

assert(osp0.ref_count() == 0);

assert(itemcount() == 1);

}

assert(itemcount() == 0);

} break; case 13: {

{

// testing move assignment

smart_ptr osp0 {new OurType{0}};

assert(osp0.ref_count() == 1);

assert(itemcount() == 1);

smart_ptr osp1;

osp1 = std::move(osp0);

assert(osp1.ref_count() == 1);

assert(osp0.ref_count() == 0);

assert(itemcount() == 1);

}

assert(itemcount() == 0);

} break; case 14: {

{

// testing assignment operator

smart_ptr osp0;

assert(itemcount() == 0);

smart_ptr osp1;

osp1 = osp0;

assert(itemcount() == 0);

}

assert(itemcount() == 0);

} break; case 15: {

try {

*dsp0;

assert(0);

}

catch (...) { }

} break; case 16: {

smart_ptr osp{new OurType{42}};

try {

assert((*osp).m_value==42);

}

catch (...) {

assert(0);

}

} break; case 17: {

smart_ptr osp;

try {

(*osp).m_value; // should throw

assert(0);

}

catch (...) { }

} break; case 18: {

smart_ptr osp{new OurType{42}};

try {

assert(osp->m_value == 42);

}

catch (...) {

assert(0);

}

} break; case 19: {

smart_ptr osp;

try {

osp->m_value; // should throw

assert(0);

}

catch (...) { }

} break; case 20: {

assert(!dsp0.clone());

assert(!dsp1.clone());

} break; case 21: {

dsp3 = dsp2 = dsp1;

assert(dsp1.clone());

assert(dsp1.ref_count() == 1 && dsp2.ref_count() == 2 && dsp3.ref_count() == 2);

assert(*dsp1 == 3.14 && *dsp2 == 3.14 && *dsp3 == 3.14);

} break; case 22: {

dsp3 = dsp2 = dsp1;

recordaddrs = true;

throwBadAlloc = 1; // first allocation throws exception

size_t oldSize = addrs.size();

try {

dsp1.clone();

assert(0);

}

catch(std::bad_alloc) { }

// test for strong guarantee, no change to dsp1

assert(*dsp1 == *dsp2 && dsp1.ref_count() == dsp2.ref_count());

assert(addrs.size() == oldSize);

recordaddrs = false;

} break; case 23: {

dsp3 = dsp2 = dsp1;

recordaddrs = true;

throwBadAlloc = 2; // second alocation throws exception

size_t oldSize = addrs.size();

try {

dsp1.clone();

assert(0);

}

catch(std::bad_alloc) { }

// test for strong guarantee, no change to dsp1

assert(*dsp1 == *dsp2 && dsp1.ref_count() == dsp2.ref_count());

assert(addrs.size() == oldSize);

recordaddrs = false;

} break; case 24: {

dsp3 = dsp2 = dsp1;

assert(*dsp1 == *dsp2 && *dsp2 == *dsp3 && *dsp1 == 3.14);

assert(dsp1.ref_count() == dsp2.ref_count() &&

dsp2.ref_count() == dsp3.ref_count() &&

dsp1.ref_count() == 3);

} break; case 25: {

dsp3 = dsp2 = dsp1;

dsp3 = dsp0;

assert(*dsp1 == *dsp2 && *dsp1 == 3.14);

assert(dsp1.ref_count() == dsp2.ref_count() &&

dsp1.ref_count() == 2 &&

dsp3.ref_count() == 0);

}

}

}

int main()

{

cout << "Enter a test number (1 to 25): ";

int n;

cin >> n;

if (n < 1 || n > 25)

{

cout << "Bad test number" << endl;

return 1;

}

testone(n);

cout << "Passed test " << n << endl;

}

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Advances In Spatial And Temporal Databases 11th International Symposium Sstd 2009 Aalborg Denmark July 8 10 2009 Proceedings Lncs 5644

Authors: Nikos Mamoulis ,Thomas Seidl ,Kristian Torp ,Ira Assent

2009th Edition

3642029817, 978-3642029813

More Books

Students also viewed these Databases questions

Question

Organizing Your Speech Points

Answered: 1 week ago