i use the term new pretty loosly. so i know that there are pointer containers in the stl, like auto_ptr and shared_ptr. i dont know what these do, but i do know that i am bad with my memory management and want to make a pointer container. if i want to make it behave just like a regular pointer, except with out of bounds checks and auto garbage collection, how difficult would this be?
The garbage collection is what 'unique_ptr' is for, but don't let that stop you from figuring out a way to do it yourself. The hardest part I think would be that when you use an asterex or an ampersand to either reference or dereference a pointer, you aren't actually using them as operators so I don't know if you can "Overload" them.
ok so i ran into some trouble. right now the only thing the container does is hold one value and can then print it, but its giving me a weird conversion error that i dont understand. here is my code:
pointer.hpp
test.cpp: In function 'int main()':
test.cpp:7:16: error: assignment of function 'pointer<int> pointerOne()'
pointerOne = 10;
^
test.cpp:7:16: error: cannot convert 'int' to 'pointer<int>()' in assignment
This is a function prototype. Not an object. Lose the parenthesis.
naraku wrote:
For this pointerOne = 10; to work you need something like pointer<T>& operator=(const T&);
FWIW I would not recommend that. pointerOne = 10;should give you a compiler error.
*pointerOne = 10; should be valid syntax... for which you should overload the unary * operator.
You don't want to blur the lines between pointer and object. Assigning your pointer should change the pointer. Assigning the object should change the object.
Case in point... what if you have a type where the pointer is ambiguous?
1 2
pointer<constchar*> x;
x = "foobar"; // is this assigning x? or *x?
test.cpp: In function 'int main()':
test.cpp:7:16: error: no match for 'operator=' (operand types are 'pointer<int>' and 'int')
pointerOne = 10;
^
test.cpp:7:16: note: candidates are:
In file included from test.cpp:2:0:
pointer.hpp:16:21: note: pointer<t>& pointer<t>::operator=(t&) [with t = int]
pointer<t>& operator=(t&);
^
pointer.hpp:16:21: note: no known conversion for argument 1 from 'int' to 'int&'
pointer.hpp:7:7: note: pointer<int>& pointer<int>::operator=(const pointer<int>&)
class pointer
^
pointer.hpp:7:7: note: no known conversion for argument 1 from 'int' to 'const pointer<int>&'
test.cpp:8:17: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
std::cout<< pointerOne << std::endl;
^
In file included from /home/dtscode/Desktop/gcc-4.8.1/include/c++/4.8.1/iostream:39:0,
from test.cpp:1:
/home/dtscode/Desktop/gcc-4.8.1/include/c++/4.8.1/ostream:602:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = pointer<int>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
fyi... thats why i put the () there because i couldnt figure out the errors
template<class t = int>
class pointer
{
int size = 1;
t *value = new t(size); // <- this is misleading. 'size' is not actually the size, it's just
// the value to initialize the single integer with. Did you mean to use [square]
// brackets here to indicate array allocation? I'm going to assume no... because if the
// answer is yes then a lot of your below code doesn't make sense.
public:
pointer() { } // <- lose the <t> here... the constructor is not templated, the class is
~pointer() // <- same deal here
{ delete value; }
t& operator=(t& newValue) // again, I don't like this because it blurs line between pointer/pointee
{ // a proper assignment operator would re-seat the pointer
*value = *newValue; // <- this is also wrong, as you're trying to dereference newValue which isn't a pointer
return newValue; // <- you typically want to return THIS object rather than the passed in object. *value would be a more typical return value here.
}
// again.. this is more line blurring. If the user wants to print the object, let them print
// the object themselves. If they print the pointer... you should be printing the pointer.
template<class i>
friend std::ostream& operator<<(std::ostream&, const pointer<i> &rvalue)
{
out<< rvalue.getValue();
return out;
}
// This is a less functional version of the * operator.... you could probably get rid of this
t getValue() { return *value; }
};
how do i overload operator *?
The syntax is the same as overloading any other operator. The only difference is with the * operator you want to return a reference to the object so the caller can treat it like it's actually accessing the object:
// <- this is misleading. 'size' is not actually the size, it's just
// the value to initialize the single integer with. Did you mean to use [square]
// brackets here to indicate array allocation? I'm going to assume no... because if the
// answer is yes then a lot of your below code doesn't make sense.
yes i meant to do [Size]. how does my code not make sense? thats not defending it. i really am confused. this is my first container and like i said im bad with memory management. (thats why im building the container)
// again, I don't like this because it blurs line between pointer/pointee
{ // a proper assignment operator would re-seat the pointer
could you rephrase? what do you mean by re-seat?
// again.. this is more line blurring. If the user wants to print the object, let them print
// the object themselves. If they print the pointer... you should be printing the pointer
yes i meant to do [Size]. how does my code not make sense? thats not defending it. i really am confused
You're using singular delete (delete instead of delete[] like you'd need to for array new).
And a getValue() style function doesn't really work well with an array. Get which value? Element [0]?
Your assignment operator only assigns element 0 as well.. which also doesn't really make sense with an array.
Overloading the [] operator would make more sense if this is an array container.
You also don't give any way to specify the size, so size is always default constructed to 1.
could you rephrase? what do you mean by re-seat?
Make the pointer point to something else.
IE this code:
1 2 3 4 5 6 7
pointer<int> foo;
int bar = newint[6];
foo = bar; // If this is allowed... I would expect this to make 'foo' take ownership of
// my 'bar' array. That is, I'm assigning one pointer to another. I would not expect
// this to do a deep copy.
// though note that most smart pointer classes don't even allow this
The idea is that your pointer class is simulating the behavior of a pointer. So if you want the class to act and feel natural, the syntax for using it should be similar to that of a normal pointer.
You're using singular delete (delete instead of delete[] like you'd need to for array new).
oh ok.
And a getValue() style function doesn't really work well with an array. Get which value? Element [0]?
it was more meant for getting the current value t *value points to.
our assignment operator only assigns element 0 as well.. which also doesn't really make sense with an array.
i know. right now i just wanted to get those three things working because they seemed like the brunt of it then i was going to make traversable with +, -, ++, -- and [].
i forgot to allow them to specifiy size. and as to your last part ok.