I wrote a class to manage pointers better (because I am making a large program and don't want to call a constructor on somthing that was already deleted... etc...), but I am getting some compiler errors. I'm not sure what to do.
template<typename type>
class pointer_class{
public:
pointer_class() : dat(NULL), del(false) {}
explicit pointer_class(const pointer_class<type>& d) : dat(NULL),
del(d.del) {
if(del)
{
this->dat = new type(*d.dat);
}
if(!del)
{
this->dat = d.dat;
}
}
explicit pointer_class(type* d) : dat(d), del(true) {}
explicit pointer_class(type& d) : dat(&d), //error here (invalid conversion??)
del(false) {}
~pointer_class()
{
if(del)
{
delete dat;
}
}
booloperator==(const pointer_class& d)
{
return (*(d.dat) == *(this->dat));
}
pointer_class<type> operator=(const type& d)
{
*this = pointer_class(d);
return *this;
}
/* Allows modification of dat, as well as access to member functions,
* but not the pointer. */
type& gdata()
{
return *(this->dat);
}
type gdata_const() const
{
return *(this->dat);
}
private:
type *dat;
constbool del;
};
Here are the compiler errors:
path_selection_class.h: In member function 'path_selection_class& path_selection_class::operator=(const path_selection_class&)':
In file included from browse_filesystem.cpp:16:0:
path_selection_class.h:32:25: error: use of deleted function 'pointer_class<std::vector<std::basic_string<char> > >& pointer_class<std::vector<std::basic_string<char> > >::operator=(const pointer_class<std::vector<std::basic_string<char> > >&)'
this->paths = s.paths;
^
In file included from vector_display_buff.h:13:0,
from browse_filesystem.cpp:10:
pointer_class.h:16:7: note: 'pointer_class<std::vector<std::basic_string<char> > >& pointer_class<std::vector<std::basic_string<char> > >::operator=(const pointer_class<std::vector<std::basic_string<char> > >&)' is implicitly deleted because the default definition would be ill-formed:
class pointer_class{
^
pointer_class.h:16:7: error: non-static const member 'const bool pointer_class<std::vector<std::basic_string<char> > >::del', can't use default assignment operator
pointer_class.h: In instantiation of 'pointer_class<type>::pointer_class(const type&) [with type = std::vector<std::basic_string<char> >]':
path_selection_class.h:18:19: required from here
pointer_class.h:27:22: error: invalid conversion from 'const std::vector<std::basic_string<char> >*' to 'std::vector<std::basic_string<char> >*' [-fpermissive]
del(false) {}
^
I can not think of any way to solve this issue... I added a copy constructor, but alas, I have not been successful.
path_selection_class.h: In member function 'path_selection_class& path_selection_class::operator=(const path_selection_class&)':
In file included from browse_filesystem.cpp:16:0:
path_selection_class.h:32:25: error: use of deleted function 'pointer_class<std::vector<std::basic_string<char> > >& pointer_class<std::vector<std::basic_string<char> > >::operator=(const pointer_class<std::vector<std::basic_string<char> > >&)'
this->paths = s.paths;
^
In file included from vector_display_buff.h:13:0,
from browse_filesystem.cpp:10:
pointer_class.h:16:7: note: 'pointer_class<std::vector<std::basic_string<char> > >& pointer_class<std::vector<std::basic_string<char> > >::operator=(const pointer_class<std::vector<std::basic_string<char> > >&)' is implicitly deleted because the default definition would be ill-formed:
class pointer_class{
^
pointer_class.h:16:7: error: non-static const member 'const bool pointer_class<std::vector<std::basic_string<char> > >::del', can't use default assignment operator
Because I don't want to. I want to do somthin specific.
Also, i recognize this problem revolves around the fact I can't modify a const member variable of the class without an initializer list (am I wrong??), so is there some way to do this?
ah, I fixed it. I kept the member var const, and created a copy-operator. I have the bool const because it should NEVER EVER change between instances of the class. However, I want to be able to make one equal to another (which means deleting memory if it was allocated to the class, and re-assigning al the variables), so I thought I could not use the operator. I can though.
@xerzi
Not just for vector: for any variable type. I want to be able to create pointers, without warping my train of though by trying to figure out if a variable allocated new space, or just pointes to somthing that already exists. With this class, all I have to do is assign a variable using the new declaration with the constructor call of the object.
Example of emplementation:
1 2 3 4 5 6
//I want to create a string:
pointer_class<string> mystring(new string("Hello World!!"));
//what if I want to use the member of another class, but dont want to copy EVERYTHING??
string my_long_string("whatever...");
pointer_class<string> a_copy(my_long_string); //a_copy points to, and directly modifies, my_long_string
The whole reason I wanted to make this class was because I am emplementing an object oriented design for a very larg program I'm creating. I do not want to copy, say, a vector of 2,000 strings just to save it as a group to a file.
int* x = newint(5);
int y = 7;
{
pointer_class<int> xptr(x);
pointer_class<int> xptr(y);
xptr = yptr;
}
When does the memory allocated in line 1 get freed?
Where are you writing xptr.dat in line 43 of your code?
Edit:
You've got the right idea, but you really need to pay attention to when you are deleting things. Your code may work like a charm the way you are currently using it, but there a number of holes that could get you into trouble.
The class is not meant for that. Never pass the address of an existing variable, only the variable itself (and it's address will be taken by the class). That instance is undefined.
As for your second example, the space will not be freed by the class, but by the deconstruction of the object that holds the information. Note that if the class was to delete data stored in x or y, then when their respective deconstructors are called, they would try to de-allocate space that was already deallocated by my class.
@doug:
xptr.dat... what is that supposed to be? This is in C++.
Also, I know: passing a pointer to it, then deleteing the pointer and calling the deconstructor. But that's not the reason I added that constructor: I added it so that the pointer could allocate new space and act as a new variable, and not point to another, independent variable. If you have a better suggestion, I will listen.
****************************************************************
Also, to anyone else who has any way to improve this class, please let me know.
Also, what do you mean by "the redundancy of useing it with said class"?
Also, if I pass a reference, then I am just initializing a pointer with the address... otherwise, I don't see any way to assign a variable's address.... Unless you know a way...
1 2 3 4 5 6 7 8
class myclass{
public:
myclass(constint& i) : x(i) {} //passing by reference, but we are still copying the variable to x...
private:
int x;
};
I don't think it is wise to pass an object by reference and then retain that object. It'd be better to do it by a pointer so that the user knows explicitly that they are giving an object a pointer to it which it could potentially store it for use later.
If you plan on using the same resource across multiple classes consider looking into std::shared<>, that way the lifetime of the object would be guaranteed. It really depends on what you are doing, for instance:
I do not want to copy, say, a vector of 2,000 strings just to save it as a group to a file
i don't see why you can't just pass the vector by reference to a function that would then save it to a file, though your chose of wording makes your statement very unclear as to what you are doing.
A user selects a group of filesystem directories, and chooses to save them into a group of favorites.
Which is better:
A: copy the entire list (duplicating it) into the class, which will process, and add it, into a group in the favorites list
or
B: create a pointer, and just directly reference the list, not allocating any new space that we don't need to, then immediately save the new group and destroy the list.
Better yet, I could add a member function to the class to add on the list without takeing anything out of the file, but the point is, the class would be temporary, and it would be redundant to create 2 of the same function.
Passing the list as an argument to a function is not an option, because I need it to be present during the entire existence of the class, so that any/all operations I want to do with it are available (increasing the flexibility).
Alright.... so... I made a few changes to the class. I have difficulty with pointers, due to their... odd properties. I suppose that's the reason I'm writing this class.
anyway, I made some changes:
- Setting the class equal to an object allocates new space and copies the object.
- Setting the class equal to the address, or pointer will make the class not delete the pointer (It's one way or the other... correct me if there's a way to avoid this).
- Added some correcting to the operator=()
I'm getting a runtime error, and I can't fathom what is happening!!
template<typename type>
class pointer_class{
public:
pointer_class() : dat(new type()), del(true) {}
explicit pointer_class(const type& d) : dat(new type(d)), del(true) {}
explicit pointer_class(type* d) : dat(d), del(false) {}
~pointer_class()
{
if(del)
{
deletethis->dat;
this->dat = NULL;
}
}
/* Returns boolean operator on the data pointed
to by dat.*/
booloperator==(const pointer_class<type>& d)
{
if(this->dat == NULL)
{
return (this->dat == d.dat);
}
return (*(d.dat) == *(this->dat));
}
/* Makes pointer point to d. Does not delete the
data that d stores. */
pointer_class<type>& operator=(const type& d)
{
*this = pointer_class(d);
return *this;
}
pointer_class<type>& operator=(const pointer_class<type>& d)
{
if(this->del)
{
deletethis->dat;
this->dat = NULL;
}
if(!d.del)
{
this->dat = d.dat;
}
if(d.del)
{
if(this->dat == NULL)
{
this->dat = new type();
}
if((d.dat != NULL) && (d.dat != this->dat))
{
*(this->dat) = *(d.dat);
}
}
this->del = d.del;
return *this;
}
/* Allows modification of dat, as well as access to member functions,
* but not the pointer. */
type& gdata()
{
return *(this->dat);
}
type gdata_const() const
{
return *(this->dat);
}
private:
type *dat;
bool del;
};
Runtime error happens here (in another class):
1 2 3 4 5 6 7 8 9 10 11 12 13
for(vector<string>::const_iterator it = this->paths.gdata_const().begin(); it != this->paths.gdata_const().end(); ++it)
{
if(*it == s)
{
cout<< *it<< " IS SELECTED"<< endl;
returntrue;
}
}
cout<< s<< " is not selected; "<< endl;
for(vector<string>::const_iterator it = this->paths.gdata_const().begin(); it != this->paths.gdata_const().end(); ++it)
{
cout<< "\""<< *it<< "\""<< endl; //Runtime error; it spits out a bunch of (seemingly) random stuff
}
You're creating a copy every iteration of the loop when you call gdata_const() and the iterator is that of a temporary copy that was destroyed: type gdata_const() const;