pointer wrapper class - behave just like a raw pointer - c++

I'd like a pointer wrapper class that acts just like a raw pointer but also saves a special integer along with the pointer (Type's index in the array it came from)
I managed to have it behave mostly like a pointer. I am aware that the pointer comparison solution might not be optimal but that's not my main problem.
I want the wrapper to be constructed with 2 parameters(pointer,indexToArr), unless the pointer is NULL - then I don't care about indexToArr.
The problem I'm trying to solve is how to allow returning NULL just like a normal pointer allows.
current solution uses an ASSERT. But I want something that works in compile-time. something in the spirit of a specialized template method - allowing only NULL as its argument.
Current version:
class PtrWrapper
{
public:
PtrWrapper(Type* ptr, int indToArr)
: m_ptr(ptr), m_indexToArr(indToArr){}
//allow returning NULL, only NULL
PtrWrapper(Type* ptr) : m_ptr(NULL), m_indexToArr(-1) {ASSERT(ptr == NULL);}
Type* operator->() const {return m_ptr;}
Type& operator*() const {return *m_ptr;}
int IndexToArr() const {return m_indexToArr;}
//for pointer comparison
operator Type*() const {return m_ptr;}
private:
Type* m_ptr;
int m_indexToArr;
};
Any ideas, suggestions?
Thanks,
Leo

template<typename Type>
class PtrWrapper
{
typedef struct { } NotType;
public:
Ptr() { }
Ptr(const NotType* nullPtr) { }
Ptr(Type* p, int index) { }
};
You can exploit the fact that literal NULL / 0 can be auto-cast to any pointer type. Create a type that is NOT T, and a constructor which takes a single pointer to that type which nobody will ever use. Now you can handle PtrWrapper<T> x(NULL); explicitly.
Of course as others have said, this is only going to work if NULL is known at compile-time.

Simply make a default constructor with no arguments that initializes your pointer to NULL, but make sure to have some checks in your operator* and operator-> for a NULL pointer.
Do the following:
PtrWrapper(Type* ptr) : m_ptr(ptr), m_indexToArr(0) {ASSERT(ptr != NULL);}
PtrWrapper() : m_ptr(NULL), m_indexToArr(-1) {ASSERT(ptr == NULL);}

Related

C++: usage of template for pointers with overloading arrow (->) operator

I wrote this template class for pointers usage
(I need smart pointers, but I can't use boost or C++11):
template<class T>
class TreePointer{
public:
TreePointer(){
isRefOnly=false;
data=NULL;
};
TreePointer(T* data){
this->data=data;
this->isRefOnly=false;
}
TreePointer(const TreePointer& anotherPtr){
this->data=anotherPtr.data;
this->isRefOnly=true;
}
virtual ~TreePointer(){
if (!isRefOnly){
delete data;
}
}
T* operator->() const{
return data;
}
void operator=(const TreePointer &anotherPtr){
this->data=anotherPtr.data;
this->isRefOnly=true;
}
private:
T* data;
bool isRefOnly;
};
And I have big class with many methods, like this:
class WrittenBigClassWithManyMethods{
public:
WrittenBigClassWithManyMethods(int v){
this->v=v;
}
int sum(WrittenBigClassWithManyMethods* a){
return v+a->v;
}
int v;
};
This usage of my smart pointers work perfectly:
TreePointer<WrittenBigClassWithManyMethods> tp(new WrittenBigClassWithManyMethods(5));
WrittenBigClassWithManyMethods* simpleClass=new WrittenBigClassWithManyMethods(5);
cout << tp->sum(simpleClass);
But it usage isn't work:
TreePointer<WrittenBigClassWithManyMethods> tp2(new WrittenBigClassWithManyMethods(5));
cout << tp->sum(tp2);
How i can change my template for pointers to make invoking methrod sum of class WrittenBigClassWithManyMethods with parameter of type TreePointer, without any changes for class WrittenBigClassWithManyMethods and its any usages? If this is not possible, how I minimize the changes for class WrittenBigClassWithManyMethods and its usage?
Usually you'll want to overload the unary operator * (de-reference) too, returning a T&. Then you can have both a reference and the original pointer by taking the address of the result:
tp1->method_that_takes_ref(*tp2); // With operator*()
tp1->method_that_takes_ptr(&*tp2); // Works, but syntax might be a bit surprising
Another way to get at the pointer inside would be to call operator -> directly, but that would be a bit awkward. You are likely better off providing some kind of "get" method, like the one in unique_ptr, that simply returns the raw pointer:
tp1->method_that_takes_ptr(tp2.operator->()); // Works, but ugh
tp1->method_that_takes_ptr(tp2.get()); // Much clearer
Add a conversion operator to T*:
operator T*() {
return data;
}
Now the compiler will call it whenever it wants to convert a TreePointer<SomeClass> to a SomeClass*.

does C++ have a self initializing pointer

I am a bit embarrassed of asking such a simple question:
Is there any pointer class in cpp that initializes itself with nullptr but is 100% compatible to a basic c-stylish pointer?
to write:
extern "C" void someFunction(const Struct* i_s);
std::ptr<Struct> p;
// ...
p = new Struct;
// ...
someFunction(p);
Is there such a thing?
Or maybe in boost or Qt?
Edit: to make it clear: iam not searching for a smart pointer that takes ownership of the pointer and does ref counting.
You can use the following syntax
std::unique_ptr<Struct> up{};
(or std::shared_ptr). This way, the pointer is value-initialized, i.e. nullptr is being assigned to it.
See http://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr for details about the default constructor.
If you looking for a "smart" pointer that just initialized by default with nullptr, then you can write a wrapper. A very basic version below:
#include <iostream>
template <typename T>
struct safe_ptr
{
T* _ptr;
explicit safe_ptr(T* ptr = nullptr):_ptr{ptr}{}
operator T*() const {return _ptr;}
safe_ptr& operator=(T* rhs)
{
_ptr = rhs;
return *this;
}
};
void test(int* p){}
int main()
{
safe_ptr<int> s;
if(s==nullptr)
std::cout << "Yes, we are safe!" << std::endl;
// test that it "decays"
test(s);
s = new int[10]; // can assign
delete[] s; // can delete
}
There is no such thing in C++ since all of the special pointer classes implement some form of ownership other than "maintained by someone else". You could technically use shared_ptr with an empty deleter but that adds reference counting you don't actually need.
The correct C++ solution is to just always add = 0; or = nullptr; to your raw pointer declarations that aren't initialized at declaration.
All that said, this question is tagged just as C++ so the idiomatic answer is to not use raw pointers in your code (except for non-owning cases obviously).
100% compatible to a basic c-stylish pointer
std::unique_ptr and std::shared_ptr do not have automatic conversions to a raw pointer, and that's a good thing as it would inevitably lead to horrible bugs. They take ownership, and in your comments you explicitly say:
the pointer should not take ownership of the given Pointer.
If you insist, you can define a "smart" pointer class yourself:
template <class T>
class RawPointer final
{
private:
T* raw_ptr;
public:
RawPointer(T* raw_tr) : raw_ptr(raw_ptr) {}
RawPointer() : raw_ptr(nullptr) {}
operator T*() const { return raw_ptr; }
};
struct Struct
{
};
void someFunction(const Struct* i_s);
int main()
{
RawPointer<Struct> p;
someFunction(p);
}
Is this a good idea? Probably not. You should just get into the habit of initializing your raw pointers:
Struct* p = nullptr;
On the other hand, people are thinking about a very similar addition to the standard library in the future. You may find A Proposal for the World’s Dumbest Smart Pointer an interesting read.
If this is really the behavior that you want, it would be trivial to implement it yourself in a template. Here's one such implementation:
template<class T>
class ptr_t{
T* ptr;
public:
ptr_t() : ptr(nullptr){ }
ptr_t(const ptr_t& other) : ptr(other.ptr){ }
ptr_t(T* other) : ptr(other){ }
T& operator*(){
return *ptr;
}
T* operator->(){
return ptr;
}
template<class U>
operator U(){
return (U)ptr;
}
}
However, the amount of convenience you will gain from such a device will be rather limited. You're probably much better off taking another approach.

How can I define a function that takes as a parameter a pointer value of any kind?

I'm implementing for practice a smart pointer class.
I already defined an assignment operator overload that takes another instance of the same class. Now I want to define an overload of this operator, that takes any pointer. So I should be able to do stuff like smartPointer = &someObject; or smartPointer = NULL;, etc.
How can I go about doing that? Should I pass in a void*? Something else?
As a more general question (and I know this is rarely desired): what kind of parameter tells the compiler that any pointer can be passed in?
You can use a template function to make your object allow any pointer to be assigned to it.
template<typename T>
void operator=(T* obj)
{
//Your code here
}
However, its not a smart pointer if you could assign it any raw pointers as it could be assigned to more than one smart pointer object and then there would be a problem while deleting the pointer.
Following may help:
class MySharedPointer
{
public:
template <typename T>
MySharedPointer& operator = (T* p)
{
ptr.reset(p, [](void* p) { delete static_cast<T*>(p); });
return *this;
}
// nullptr is not a pointer, so it should have its own overload.
MySharedPointer& operator = (std::nullptr_t) {
ptr.reset();
return *this;
}
private:
std::shared_ptr<void> ptr;
};
Live example

Return NULL from a C++ template

I have to create a template function that searches an element in a map variable. If the element exists, the function must return it. Otherwise it must return NULL.
template <class K, class E> E dictionary<K,E>::research(K key) {
// map<K,E> elements;
if(elements.find(key) != elements.end()) {
return elements.find(key)->second;
} else {
return NULL;
}
Since the return type is E, returning NULL gives me always an error. How can I make this work? Or I have to structure my function differently?
This is a school homework assignment and I must return NULL, no alternatives. I'd personally do differently if I could.
The design of this function is incorrect. It is perfectly possible that NULL is simply incompatible with the type E. For instance, suppose that E is a struct, or a std::string and so on.
This is a school homework assignment and I must return NULL, no alternatives.
Either your homework assignment is incorrect, or you have misunderstood its requirements. It is possible that you are expected to return a pointer to E?
Instead of returning pointers, you could consider returning something like boost::optional, i.e. a type that is either set to contain a valid object or in an invalid state. That mimics a pointer in some way, but is more explicit
The following is just to show the principle, the implementation can for sure be optimized.
template<typename T> class Optional {
public:
Optional(E e):
isValid(true),
mValue(e)
{}
Optional(): isValid(false), mValue() {}
bool isDefined() const {return isValid;}
E getOrElse(E const& other) const {return (isValid) ? (mValue) : (other);}
E get(E const {return mValue;}
private:
bool isValid;
T mValue;
};

How to create operator-> in iterator without a container?

template <class Enum>
class EnumIterator {
public:
const Enum* operator-> () const {
return &(Enum::OfInt(i)); // warning: taking address of temporary
}
const Enum operator* () const {
return Enum::OfInt(i); // There is no problem with this one!
}
private:
int i;
};
I get this warning above. Currently I'm using this hack:
template <class Enum>
class EnumIterator {
public:
const Enum* operator-> () {
tmp = Enum::OfInt(i);
return &tmp;
}
private:
int i;
Enum tmp;
};
But this is ugly because iterator serves as a missing container.
What is the proper way to iterate over range of values?
Update:
The iterator is specialized to a particular set objects which support named static constructor OfInt (code snippet updated).
Please do not nit-pick about the code I pasted, but just ask for clarification. I tried to extract a simple piece.
If you want to know T will be strong enum type (essentially an int packed into a class). There will be typedef EnumIterator < EnumX > Iterator; inside class EnumX.
Update 2:
consts added to indicate that members of strong enum class that will be accessed through -> do not change the returned temporary enum.
Updated the code with operator* which gives no problem.
Enum* operator-> () {
tmp = Enum::OfInt(i);
return &tmp;
}
The problem with this isn't that it's ugly, but that its not safe. What happens, for example in code like the following:
void f(EnumIterator it)
{
g(*it, *it);
}
Now g() ends up with two pointers, both of which point to the same internal temporary that was supposed to be an implementation detail of your iterator. If g() writes through one pointer, the other value changes, too. Ouch.
Your problem is, that this function is supposed to return a pointer, but you have no object to point to. No matter what, you will have to fix this.
I see two possibilities:
Since this thing seems to wrap an enum, and enumeration types have no members, that operator-> is useless anyway (it won't be instantiated unless called, and it cannot be called as this would result in a compile-time error) and can safely be omitted.
Store an object of the right type (something like Enum::enum_type) inside the iterator, and cast it to/from int only if you want to perform integer-like operations (e.g., increment) on it.
There are many kind of iterators.
On a vector for example, iterators are usually plain pointers:
template <class T>
class Iterator
{
public:
T* operator->() { return m_pointer; }
private:
T* m_pointer;
};
But this works because a vector is just an array, in fact.
On a doubly-linked list, it would be different, the list would be composed of nodes.
template <class T>
struct Node
{
Node* m_prev;
Node* m_next;
T m_value;
};
template <class T>
class Iterator
{
public:
T* operator->() { return m_node->m_value; }
private:
Node<T>* m_node;
};
Usually, you want you iterator to be as light as possible, because they are passed around by value, so a pointer into the underlying container makes sense.
You might want to add extra debugging capabilities:
possibility to invalidate the iterator
range checking possibility
container checking (ie, checking when comparing 2 iterators that they refer to the same container to begin with)
But those are niceties, and to begin with, this is a bit more complicated.
Note also Boost.Iterator which helps with the boiler-plate code.
EDIT: (update 1 and 2 grouped)
In your case, it's fine if your iterator is just an int, you don't need more. In fact for you strong enum you don't even need an iterator, you just need operator++ and operator-- :)
The point of having a reference to the container is usually to implement those ++ and -- operators. But from your element, just having an int (assuming it's large enough), and a way to get to the previous and next values is sufficient.
It would be easier though, if you had a static vector then you could simply reuse a vector iterator.
An iterator iterates on a specific container. The implementation depends on what kind of container it is. The pointer you return should point to a member of that container. You don't need to copy it, but you do need to keep track of what container you're iterating on, and where you're at (e.g. index for a vector) presumably initialized in the iterator's constructor. Or just use the STL.
What does OfInt return? It appears to be returning the wrong type in this case. It should be returning a T* instead it seems to be returning a T by value which you are then taking the address of. This may produce incorrect behavior since it will loose any update made through ->.
As there is no container I settled on merging iterator into my strong Enum.
I init raw int to -1 to support empty enums (limit == 0) and be able to use regular for loop with TryInc.
Here is the code:
template <uint limit>
class Enum {
public:
static const uint kLimit = limit;
Enum () : raw (-1) {
}
bool TryInc () {
if (raw+1 < kLimit) {
raw += 1;
return true;
}
return false;
}
uint GetRaw() const {
return raw;
}
void SetRaw (uint raw) {
this->raw = raw;
}
static Enum OfRaw (uint raw) {
return Enum (raw);
}
bool operator == (const Enum& other) const {
return this->raw == other.raw;
}
bool operator != (const Enum& other) const {
return this->raw != other.raw;
}
protected:
explicit Enum (uint raw) : raw (raw) {
}
private:
uint raw;
};
The usage:
class Color : public Enum <10> {
public:
static const Color red;
// constructors should be automatically forwarded ...
Color () : Enum<10> () {
}
private:
Color (uint raw) : Enum<10> (raw) {
}
};
const Color Color::red = Color(0);
int main() {
Color red = Color::red;
for (Color c; c.TryInc();) {
std::cout << c.GetRaw() << std::endl;
}
}