Thread: Ban pointers or references on classes?

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654

    Ban pointers or references on classes?

    Is it possible to ban the use of references or pointers on specific classes?
    Consider the following:
    Code:
    void foo(pp<int>&) // pp = CMemoryManager
    {
    }
    
    void foo(pp<int>*) // pp = CMemoryManager
    {
    }
    
    int main()
    {
    ppnew<int> pTest; // Creates a new class of type CMemoryManager
    foo(pTest); // I want to ban this, if possible.
    foo(&pTest); // This too, maybe.
    }
    Is it possible to ban such usage by doing something with the class? If possible, I want it only to be passed by value.

  2. #2
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    Why would you only want it passed by value, and why would you want to restrict its pass type?

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Because it's a memory manager - it keeps a reference count. For every function you pass it to, it should increase its ref count.
    And it will create less bugs and such and for fun, too.

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    If you're talking about the class constructor function, you can use the explicit keyword, otherwise you can make a function private so it can't be called.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't know how explicit works, nor what implicit and explicit actually means.
    It's not a class constructor function. I want to ban passing the an object of the type pp to another function by reference or as a pointer.
    BTW, explicit doesn't help of any constructor / copy constructor I have right now. Plus it's not calling any constructor since it's a reference. It just passes the address of the object.
    Last edited by Elysia; 10-25-2007 at 02:25 PM.

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    I suppose you could make operator &() private to prevent taking pointers of it.

    I can't think of a way to prevent references though. Void is the only type that you can't have a reference to.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Awesome! Now it's now possible to pass the object as a pointer by using &object.
    Still, there's no way to prevent references anyone know of?

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    You'd still need to make the constructors protected to prevent allocating on the heap. This is often done in conjunction with the factory pattern.

    Alternatively, you could make operator new() private in all it's forms (There are several).
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I'm not quite sure I understand?

    Do you have a particular function that you want to ban pass-by-reference for, or do you want to do it in general for every function everywhere (whether it's a function you wrote or not)?

    Is this for a class that you own & control, or for a 3rd party class?

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, for all functions in general, and yes it's my own class.
    I'm trying to prevent it because it's dangerous (for this class; it's not design to be passed by reference).

    I also encountered something weird:
    Code:
    ppnew<int>* pTest2 = new ppnew<int>;
    Of course it complains that it can't access private operator new, but it also complains it can't access private operator delete.
    If I make delete public or remove it, it compiles but there's no call to delete.
    Is it a safety precaution seeing as that after you allocate it, you can't delete it?

    So far, here's what I have:
    Code:
    void foo(pp<int>&);
    void foo(pp<int>*);
    
    ppnew<int> pTest; // Works, and should work
    ppnew<int>* pTest2 = new ppnew<int>; // Does not work - can't call private operator new and private operator delete, as it should be
    foo(pTest); // Works, but shouldn't! BAD!!!
    foo(&pTest); // Doesn't work, can't call private operator &
    foo(pTest2); // Works, but you can't allocate a new instance of the class
    Last edited by Elysia; 10-25-2007 at 05:29 PM.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I'm trying to prevent it because it's dangerous

    I don't see how it's dangerous. The reference count won't be incremented when you pass by reference or pass by pointer. It also won't be decremented when the function ends. So there's no danger.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Daved View Post
    >> I'm trying to prevent it because it's dangerous

    I don't see how it's dangerous. The reference count won't be incremented when you pass by reference or pass by pointer. It also won't be decremented when the function ends. So there's no danger.
    Why? Because if somehow the pointer counter reaches 0 while the function is using it, it will use freed memory and crash. Since the function will never increment the ref count, it's in trouble. When might that happen? I'll be honest with you that I don't really know right now. I can't think of a scenario, but that doesn't mean it won't happen. Not to mention I find it stupid to pass a pointer by reference.
    A pointer to the memory handler is even more dangerous since it wouldn't increase the ref count either and if, say, a thread uses that pointer and the other functions don't need it anymore and get rid of it, then we have a problem.

  13. #13
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Elysia View Post
    So far, here's what I have:
    Code:
    ppnew<int>* pTest2 = new ppnew<int>; // Does not work - can't call private operator
    What about:

    Code:
    ppnew<int>* pTest1 = new(std::nothrow) ppnew<int>; 
    ppnew<int>* pTest2 = new ppnew<int>[10];
    char pTest3a[sizeof(ppnew<int>)];
    ppnew<int>* pTest3b = new(pTest3a) ppnew<int>();
    And other cases.

    If you're going to hide new, you need to hide all its forms.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> Because if somehow the pointer counter reaches 0 while the function is using it, it will use freed memory and crash.
    It can't happen. Pretend the function is inline, then move the code from the function into the calling code. You're not calling any functions at that point. If you assume that code without function calls is safe, then code with function calls and pass by reference is safe.

    Assuming the constructor(s) increment the count, destructors decrement the count, and copying of the pointer is handled properly, there is no way there can be an issue. If you have a multi-threaded environment, then you need to put some sort of synchronization control around the decrement and delete areas, but that's not a problem for the code that uses the class.


    >> Not to mention I find it stupid to pass a pointer by reference.
    It does make sense in some situations to pass a pointer by reference, but I don't think that's what you meant. In this situation, if passing your class by reference doesn't make sense, that's fine, but don't worry about coming up with convoluted ways to prevent it when allowing it won't cause any problems.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It seems there are dents in the armor. pTest2 and pTest3a works.
    Here are the current overloaded news:

    Code:
    	void* operator new(size_t _Count) throw();
    	void* operator new(size_t _Count, const std::nothrow_t&) throw();
    	void* operator new(std::size_t _Count, void* _Ptr) throw();
    A thought: are these "protected" new operator inherited?
    ppnew = CMemoryManagerNew: public CMemoryManager

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointers v References
    By m37h0d in forum C++ Programming
    Replies: 28
    Last Post: 06-30-2008, 01:29 PM
  2. Replies: 12
    Last Post: 12-31-2007, 06:59 AM
  3. Pointers, Classes, and Errors o my!
    By Scottc1988 in forum C++ Programming
    Replies: 12
    Last Post: 03-13-2003, 10:14 PM
  4. Pointers to derived classes.
    By sean in forum C++ Programming
    Replies: 3
    Last Post: 11-13-2001, 08:19 PM
  5. Pointers to inherited classes
    By sean in forum C++ Programming
    Replies: 1
    Last Post: 11-03-2001, 03:04 PM