#include <iostream>
using namespace std;
template<typename T>
class smart_ptr {
private:
T *ptr_;
public:
smart_ptr(T *ptr = NULL) : ptr_(ptr) {}
operator bool() const {
if (ptr_) {
return true;
} else {
return false;
}
}
~smart_ptr() {
delete ptr_;
}
};
template<typename T>
class smart_ptr2 {
private:
T *ptr_;
public:
smart_ptr2(T *ptr = NULL) : ptr_(ptr) {}
bool operator!() const {
if (ptr_) {
return false;
} else {
return true;
}
}
~smart_ptr2() {
delete ptr_;
}
};
template<typename T>
class smart_ptr3 {
private:
T *ptr_;
public:
smart_ptr3(T *ptr = NULL) : ptr_(ptr) {}
operator void*() const {
return ptr_;
}
~smart_ptr3() {
delete ptr_;
}
};
template<typename T>
class smart_ptr4 {
private:
T *ptr_;
public:
smart_ptr4(T *ptr = NULL) : ptr_(ptr) {}
class nested_class;
operator nested_class*() const {
return ptr_ != NULL ? reinterpret_cast<nested_class*>(ptr_) : NULL;
}
~smart_ptr4() {
delete ptr_;
}
};
template<typename T>
class smart_ptr5 {
private:
T *ptr_;
typedef T *(smart_ptr5::*bool_type)() const;
void operator==(smart_ptr5 const&) const;
void operator!=(smart_ptr5 const&) const;
public:
smart_ptr5(T *ptr = NULL) : ptr_(ptr) {}
operator bool_type() const {
return ptr_ != NULL ? &smart_ptr5::get : NULL;
}
T *get() const {
return ptr_;
}
~smart_ptr5() {
delete ptr_;
}
};
void test_smart_ptr() {
smart_ptr<int> p0;
smart_ptr<int> p1;
if (p0) {
cout << "p0 is valid" << endl;
} else {
cout << "p0 is invalid" << endl;
}
p0 << 1;
cout << "p0 << 1: " << p0 << endl;
int i = p1;
cout << "int i = p1: " << i << endl;
if (p0 == p1) {
cout << "p0 == p1" << endl;
} else {
cout << "p0 != p1" << endl;
}
}
void test_smart_ptr2() {
smart_ptr2<int> p0;
smart_ptr2<int> p1;
if ( !! p0) {
cout << "p0 is valid" << endl;
} else {
cout << "p0 is invalid" << endl;
}
/*
g++: error: no match for ‘operator<<’ in ‘p0 << 1’
g++: error: cannot convert ‘smart_ptr2<int>’ to ‘int’ in initialization
p0 << 1;
cout << "p0 << 1: " << p0 << endl;
int i = p1;
cout << "int i = p1: " << i << endl;
*/
/*
g++: error: no match for ‘operator==’ in ‘p0 == p1’
if (p0 == p1) {
cout << "p0 == p1" << endl;
} else {
cout << "p0 != p1" << endl;
}
*/
}
void test_smart_ptr3() {
smart_ptr3<int> p0;
smart_ptr3<int> p1;
if (p0) {
cout << "p0 is valid" << endl;
} else {
cout << "p0 is invalid" << endl;
}
if (p0 == p1) {
cout << "p0 == p1" << endl;
} else {
cout << "p0 != p1" << endl;
}
/*
g++: error: no match for ‘operator<<’ in ‘p0 << 1’
g++: error: invalid conversion from ‘void*’ to ‘int’
p0 << 1;
cout << "p0 << 1: " << p0 << endl;
int i = p1;
cout << "int i = p1: " << i << endl;
*/
/*
g++: warning: deleting ‘void*’ is undefined
g++: warning: deleting ‘void*’ is undefined
delete p0;
delete p1;
*/
}
void test_smart_ptr4() {
smart_ptr4<int> p0;
smart_ptr4<int> p1;
if (p0) {
cout << "p0 is valid" << endl;
} else {
cout << "p0 is invalid" << endl;
}
if (p0 == p1) {
cout << "p0 == p1" << endl;
} else {
cout << "p0 != p1" << endl;
}
/*
g++: error: no match for ‘operator<<’ in ‘p0 << 1’
g++: error: invalid conversion from ‘smart_ptr4<int>::nested_class*’ to ‘int’
p0 << 1;
cout << "p0 << 1: " << p0 << endl;
int i = p1;
cout << "int i = p1: " << i << endl;
*/
/*
g++: warning: possible problem detected in invocation of delete operator:
g++: warning: invalid use of incomplete type ‘struct smart_ptr4<int>::nested_class’
g++: warning: declaration of ‘struct smart_ptr4<int>::nested_class’
g++: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
delete p0;
delete p1;
*/
}
void test_smart_ptr5() {
smart_ptr5<int> p0;
smart_ptr5<int> p1;
if (p0) {
cout << "p0 is valid" << endl;
} else {
cout << "p0 is invalid" << endl;
}
/*
g++: error: ‘void smart_ptr5<T>::operator==(const smart_ptr5<T>&) const [with T = int]’ is private
g++: within this context
g++: could not convert ‘p0.smart_ptr5<T>::operator== [with T = int](((const smart_ptr5<int>&)((const smart_ptr5<int>*)(& p1))))’ to ‘bool’
if (p0 == p1) {
cout << "p0 == p1" << endl;
} else {
cout << "p0 != p1" << endl;
}
*/
/*
g++: error: no match for ‘operator<<’ in ‘p0 << 1’
g++: error: cannot convert ‘smart_ptr5<int>’ to ‘int’ in initialization
p0 << 1;
cout << "p0 << 1: " << p0 << endl;
int i = p1;
cout << "int i = p1: " << i << endl;
*/
/*
g++: error: type ‘class smart_ptr5<int>’ argument given to ‘delete’, expected pointer
g++: error: type ‘class smart_ptr5<int>’ argument given to ‘delete’, expected pointer
delete p0;
delete p1;
*/
}
int main(void) {
test_smart_ptr();
test_smart_ptr2();
test_smart_ptr3();
test_smart_ptr4();
test_smart_ptr5();
return 0;
}