Pointers to members and accessors

Started by
6 comments, last by b3rs3rk 16 years, 5 months ago
I have some doubts about class accessors. In a nutshell, assume you have a class like this:

class CTest{
public:
	CTest() { 
		mlist = new int*[10];
		for(int i=0;i<10;i++){
			mlist = new int(i); 
		}

		curr_elem = mlist[4]; 
	}

	int *GetCurr() { return curr_elem; }

private:
	int **mlist;
	int *curr_elem;
};

So we have an array of 10 int pointers with values from 0 to 9, and another int pointer to the element at location 4. Cool. Now if I do something like this:

CTest p;
int* point = p.GetCurr();
delete point;

both curr_elem and mlist[4] point to nothing (err... actually they point to a unknow memory location, but it is the same :D ) Is there a way to make impossible the "delete point" call? Or at least, to do not corrupt the private members of CTest ?
Advertisement
You can't prevent the programmer from obtaining a reference to your value, and from there the address, and from there deleting the pointer to that address, unless you return your result by value (at which point the element in your class is unaffected).

Your best bet is to return a reference instead—while evilness is still possible, you should not contrive your code to defend yourself against malice or gross incompetence.
Quote:Is there a way to make impossible the "delete point" call? Or at least, to do not corrupt the private members of CTest ?


Yes, references.

int &GetCurr() { return *curr_elem; }


They aren't ideal, but they do the job of protecting the members.
Iterators would be another solution.

Also: your allocation code is pure evil.
thank you :)

@Antheus: using an accessor like you said could bring speed problems / slow code?

OT: why the allocation code is pure evil? :D
Quote:Original post by b3rs3rk
@Antheus: using an accessor like you said could bring speed problems / slow code?


No.

Quote:OT: why the allocation code is pure evil? :D


You allocate too many objects for no reason, you allocate an array of pointers dynamically, you allocate individual integers for no reason, you don't have any kind of exception-safety, and you don't clean up after yourself. Your constructor doesn't do anything that an std::vector<int> wouldn't do, but it certainly doesn't do certain useful things that std::vector<int> does.
Unless I'm mistaking, if you can directly access some data (and not a copy of it), then you automatically must know where it is, and should be able to get a pointer to it, which you can delete. Using references can help, but you can still get the adress of a reference.

Take auto_ptr, you could always do :
auto_ptr<int> myPtr(new int);
delete myPtr.get();
delete &(*myPtr);

Of course you can do it, but, in the end, you're the only one who's going to suffer, not the guy(s) who wrote auto_ptr.

Face it : you're using C++. There's no way you can prevent the user of your code to make their application crash. The only thing you can do is return references instead of pointers, just to be safer. There's nothing wrong with allowing the user to access some references. If the user decides to delete it, he's blowing his own head off. It's his problem. To quote some movie : "With great power comes great responsabilities"!
In this particular case since sizeof(int) is the same as sizeof(int*), you can return by value without any overhead:

int GetCurr() { return *curr_elem; }


but then of course if you change the returned value, it would not change inside the object, you would need a setter for that (SetCurr).
I'll use more references :D Thanks!

This topic is closed to new replies.

Advertisement