Morgan Stanley Interview Question
Financial Software DevelopersCountry: United States
Interview Type: In-Person
#include<iostream>
template<class T>
class sharedPtr
{
T* ShrdPtr;
mutable int* refCount;
public:
sharedPtr( T* ptr ) { ShrdPtr = ptr; refCount = new int(); *refCount = 1; }
~sharedPtr( )
{
std::cout << "inside destructor refCount = " << *refCount << "\n";
if( --(*refCount) == 0 )
delete ShrdPtr;
}
T& operator=( const sharedPtr& ptr );
sharedPtr( const sharedPtr& ptr );
T* operator->( ) { return ShrdPtr; }
T& operator*() { return *ShrdPtr; }
};
template<class T>
T& sharedPtr<T>::operator=( const sharedPtr& ptr )
{
std::cout << "inside assignment operator\n";
this->ShrdPtr = ptr.ShrdPtr;
(*(ptr.refCount))++;
this->refCount = ptr.refCount;
return *this;
}
template<class T>
sharedPtr<T>::sharedPtr( const sharedPtr& ptr )
{
std::cout << "inside copy constructor\n";
this->ShrdPtr = ptr.ShrdPtr;
(*(ptr.refCount))++;
this->refCount = ptr.refCount;
}
int main( int argc, char* argv[] )
{
sharedPtr<int> p = new int;
{
sharedPtr<int> q = p;
}
return 0;
}
Here is my Implementation of shared ptr:
// shared_pointer.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <exception>
using namespace std;
template <class T> class sh_ptr
{
private:
T* ptr;
static int count;
public:
sh_ptr() {
ptr = new T;
count++;
cout << "count = " << count << endl;
}
~sh_ptr() {
// check count before deleting the pointer
cout << " count before = " << count << endl;
count--;
cout << " count after = " << count << endl;
if ( !count)
{
if (ptr) delete ptr;
ptr = NULL;
}
}
// implement sssignment and copy operation because shared pointer
// does copy and assignment. So it is named as shared pointer
// make sure that the copy constructor will invoke additional
// pointer to that heap memory and one additional counter
// no deep copy is required. For assignment operator
// we may require a deep copy as they already point to two different memory location.
// or we may not write a assignment operator
// We have to implement operator-> to exhibit the pointer behavior.
sh_ptr(sh_ptr& d){
ptr = d.ptr;
count++ ;
}
sh_ptr& operator=(sh_ptr& d){
// here is a memory leak for new, so first delet the new
// before assigning the pointer to another memory location
delete d.ptr;
ptr = d.ptr;
count++ ;
return *this;
}
void fun()
{
cout << " this is a fun" << endl;
}
sh_ptr<T>* operator->()
{
return (this);
}
};
template < class T> int sh_ptr<T>::count=0;
int main(int argc, char* argv[])
{
{
sh_ptr<int> obj;
obj->fun();
sh_ptr<int> obj2 = obj;
sh_ptr<int> obj7;
obj7 = obj;
}
cout << " new object" << endl;
sh_ptr<float> obj3;
sh_ptr<double> obj4;
return 0;
}
template < typename T > class SP
{
private:
T* pData; // pointer
RC* reference; // Reference count
public:
SP() : pData(0), reference(0)
{
// Create a new reference
reference = new RC();
// Increment the reference count
reference->AddRef();
}
SP(T* pValue) : pData(pValue), reference(0)
{
// Create a new reference
reference = new RC();
// Increment the reference count
reference->AddRef();
}
SP(const SP<T>& sp) : pData(sp.pData), reference(sp.reference)
{
// Copy constructor
// Copy the data and reference pointer
// and increment the reference count
reference->AddRef();
}
~SP()
{
// Destructor
// Decrement the reference count
// if reference become zero delete the data
if(reference->Release() == 0)
{
delete pData;
delete reference;
}
}
T& operator* ()
{
return *pData;
}
T* operator-> ()
{
return pData;
}
SP<T>& operator = (const SP<T>& sp)
{
// Assignment operator
if (this != &sp) // Avoid self assignment
{
// Decrement the old reference count
// if reference become zero delete the old data
if(reference->Release() == 0)
{
delete pData;
delete reference;
}
// Copy the data and reference pointer
// and increment the reference count
pData = sp.pData;
reference = sp.reference;
reference->AddRef();
}
return *this;
}
};
wtf.. why is everyone making the refcount an pointer and new'ing it? What's wrong with an int?
#ifndef SHAREDPOINTER_H_
#define SHAREDPOINTER_H_
class RefCountMgr
{
public:
RefCountMgr():m_ref_count(0){}
void incrementRefCount(){ ++m_ref_count; }
void decrementRefCount() { --m_ref_count; }
int getRefCount() const {return m_ref_count;}
private:
int m_ref_count;
};
template<typename T>
class SharedPointer
{
public:
SharedPointer():m_t(0),m_ref_count_mgr(0){}
SharedPointer(T* t):m_t(t)
{
m_ref_count_mgr = new RefCountMgr();
m_ref_count_mgr->incrementRefCount();
}
~SharedPointer()
{
if(m_ref_count_mgr)
{
m_ref_count_mgr->decrementRefCount();
if(m_ref_count_mgr->getRefCount() <= 0)
{
delete m_t;
m_t = 0;
delete m_ref_count_mgr;
m_ref_count_mgr = 0;
}
}
}
SharedPointer(const SharedPointer& other)
{
m_t = other.m_t;
m_ref_count_mgr = other.m_ref_count_mgr;
m_ref_count_mgr->incrementRefCount();
}
SharedPointer& operator=(const SharedPointer& other)
{
if(this == &other)
return *this;
this->~SharedPointer();
m_t = other.m_t;
m_ref_count_mgr = other.m_ref_count_mgr;
m_ref_count_mgr->incrementRefCount();
return *this;
}
int refcount() const
{
if(m_ref_count_mgr)
return m_ref_count_mgr->getRefCount();
return 0;
}
T& operator*() const
{
return *m_t;
}
T* operator->() const
{
return m_t;
}
private:
RefCountMgr* m_ref_count_mgr;
T* m_t;
};
#endif /* SHAREDPOINTER_H_ */
#ifndef SHAREDPOINTER_H_
#define SHAREDPOINTER_H_
class RefCountMgr
{
public:
RefCountMgr():m_ref_count(0){}
void incrementRefCount(){ ++m_ref_count; }
void decrementRefCount() { --m_ref_count; }
int getRefCount() const {return m_ref_count;}
private:
int m_ref_count;
};
template<typename T>
class SharedPointer
{
public:
SharedPointer():m_t(0),m_ref_count_mgr(0){}
SharedPointer(T* t):m_t(t)
{
m_ref_count_mgr = new RefCountMgr();
m_ref_count_mgr->incrementRefCount();
}
~SharedPointer()
{
if(m_ref_count_mgr)
{
m_ref_count_mgr->decrementRefCount();
if(m_ref_count_mgr->getRefCount() <= 0)
{
delete m_t;
m_t = 0;
delete m_ref_count_mgr;
m_ref_count_mgr = 0;
}
}
}
SharedPointer(const SharedPointer& other)
{
m_t = other.m_t;
m_ref_count_mgr = other.m_ref_count_mgr;
m_ref_count_mgr->incrementRefCount();
}
SharedPointer& operator=(const SharedPointer& other)
{
if(this == &other)
return *this;
this->~SharedPointer();
m_t = other.m_t;
m_ref_count_mgr = other.m_ref_count_mgr;
m_ref_count_mgr->incrementRefCount();
return *this;
}
int refcount() const
{
if(m_ref_count_mgr)
return m_ref_count_mgr->getRefCount();
return 0;
}
T& operator*() const
{
return *m_t;
}
T* operator->() const
{
return m_t;
}
private:
RefCountMgr* m_ref_count_mgr;
T* m_t;
};
#endif /* SHAREDPOINTER_H_ */
many errors in your code.
- jianbozhu May 12, 2012for instance. ctor should never return and its parameter must be const reference.