operator= could not be generated

Discussion in 'C++' started by Jeffrey Walton, Jul 8, 2010.

  1. Hi All,

    I'm working with some C++ code that performs a lot of heap allocations
    on typef'd structs, structs, and classes, but does not ensure cleanup.
    Many of the classes and structs hide their assignment operator.

    I attempted to write a template class to ensure cleanup, but am
    receiving the error, "operator= could not be generated".

    Two questions. (1) I'm dealting with pointers and not objects. So why
    is an assignmnet operator needed? (2) I know the void* hack is
    bullshit. How do I accomplish my goals of the delete, and then set the
    pointer to NULL.

    Thanks,
    Jeff

    template <class T>
    PtrTypeCleanup<T>::ptrTypeCleanup(T*& ptr)
    : m_ptr(NULL)
    {
    // Most types have their assignment operator hidden.
    // Cast so that we can set the bastard to NULL.
    reinterpret_cast<void*>(m_ptr) = reinterpret_cast<void*>(ptr);
    }

    template <class T>
    PtrTypeCleanup<T>::~PtrTypeCleanup(void)
    {
    if(m_ptr)
    {
    // We must delete through the type
    delete m_ptr;
    // Most types have their assignment operator hidden.
    // Cast so that we can set the bastard to NULL.
    // void* p = reinterpret_cast<void*>(m_ptr);
    // p = NULL;
    }
    }

    template <class T>
    void PtrTypeCleanup<T>::Release(void)
    {
    // Most types have their assignment operator hidden.
    // Cast so that we can set the bastard to NULL.
    // void* p = reinterpret_cast<void*>(m_ptr);
    // p = NULL;
    }

    template <class T>
    T*& PtrTypeCleanup<T>::eek:perator=(const T*& rhs)
    {
    // No self assignment
    if(this == &rhs) { return *this; }

    reinterpret_cast<void*>(m_ptr) =
    reinterpret_cast<void*>(rhs.m_ptr);
    }
     
    Jeffrey Walton, Jul 8, 2010
    #1
    1. Advertising

  2. On 7/8/2010 4:23 PM, Jeffrey Walton wrote:
    > I'm working with some C++ code that performs a lot of heap allocations
    > on typef'd structs, structs, and classes, but does not ensure cleanup.
    > Many of the classes and structs hide their assignment operator.
    >
    > I attempted to write a template class to ensure cleanup, but am
    > receiving the error, "operator= could not be generated".


    Error? Are you sure? Not a warning?

    > Two questions. (1) I'm dealting with pointers and not objects. So why
    > is an assignmnet operator needed?


    Usually the assignment operator is used when you *assign* to the object
    of your class. Since you didn't post any code showing how you operate
    on your objects (of type PtrTypeCleanup), I can't be more specific.
    Please see FAQ 5.8.

    > (2) I know the void* hack is
    > bullshit. How do I accomplish my goals of the delete, and then set the
    > pointer to NULL.


    Deleting and setting WHAT to NULL? 'm_ptr'? How is it declared?

    > [..]


    The assignment operator cannot be generated usually if your class has a
    member with an inaccessible assignment operator, or a constant data
    member, etc., IOW a member which does not have assignment semantics.

    Since you elected not to post the definition of your class, I can't be
    more specific. Please see FAQ 5.8.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jul 8, 2010
    #2
    1. Advertising

  3. Hi Victor,

    My apologies again. I missed another detail.....

    On Jul 8, 4:52 pm, Victor Bazarov <> wrote:
    > On 7/8/2010 4:23 PM, Jeffrey Walton wrote:
    >
    > > I'm working with some C++ code that performs a lot of heap allocations
    > > on typef'd structs, structs, and classes, but does not ensure cleanup.
    > > Many of the classes and structs hide their assignment operator.

    >
    > > [SNIP]

    >
    > > Two questions. (1) I'm dealting with pointers and not objects. So why
    > > is an assignmnet operator needed?

    >
    > Usually the assignment operator is used when you *assign* to the object
    > of your class.  Since you didn't post any code showing how you operate
    > on your objects (of type PtrTypeCleanup), I can't be more specific.

    Here's how this might be used:

    CSomeClass* someClass = new someClass;
    PtrTypeCleanup<CSomeClass> cleanup(someClass);

    // Do useful things with someClass. Upon an exception,
    // I'm ensured the class is cleaned up. I'm also ensured
    // that the original pointer is NULL in an attempt to
    // vet pointer reuse.

    Recall from my statement above, CSomeClass might (and probably does)
    have a hidden operator=.

    > Please see FAQ 5.8.

    I cringe when I have to do anything with this solution. There are
    nearly 900 source files which produce 7 executable modules with
    everything inter-twinded. I probably could not give you a concrete
    example without including at least 20 source files.

    Do you really need concrete examples that compile and link for an
    abstract question? Ie, why do I need an operator= when I'm dealing
    with pointers.

    >
    >  [SNIP]


    Jeff
     
    Jeffrey Walton, Jul 8, 2010
    #3
  4. Jeffrey Walton

    Jonathan Lee Guest

    On Jul 8, 5:48 pm, Jeffrey Walton <> wrote:
    > Here's how this might be used:
    >
    > CSomeClass* someClass = new someClass;
    > PtrTypeCleanup<CSomeClass> cleanup(someClass);
    >
    > // Do useful things with someClass. Upon an exception,
    > // I'm ensured the class is cleaned up. I'm also ensured
    > // that the original pointer is NULL in an attempt to
    > // vet pointer reuse.


    If you can change your usage pattern slightly you
    could probably get away with using std::auto_ptr or
    one of the Boost smart pointers.

    Specifically, I think you're going to have a lot of
    problems with trying to clear the original pointer.
    A better pattern might be

    auto_ptr<CSomeClass> cleanup(new CSomeClass);
    CSomeClass* someClass = cleanup.get();

    In this arrangement, you don't have to actually set
    someClass to null. It has a shorter lifetime than
    cleanup (unless you reset cleanup or something).

    I don't see where operator= enters into it, since
    you're assigning pointers, not objects.

    --Jonathan
     
    Jonathan Lee, Jul 8, 2010
    #4
  5. Jeffrey Walton

    James Kanze Guest

    On Jul 8, 9:23 pm, Jeffrey Walton <> wrote:
    > I'm working with some C++ code that performs a lot of heap allocations
    > on typef'd structs, structs, and classes, but does not ensure cleanup.
    > Many of the classes and structs hide their assignment operator.


    > I attempted to write a template class to ensure cleanup, but am
    > receiving the error, "operator= could not be generated".


    > Two questions. (1) I'm dealting with pointers and not objects. So why
    > is an assignmnet operator needed? (2) I know the void* hack is
    > bullshit. How do I accomplish my goals of the delete, and then set the
    > pointer to NULL.


    I'm not quite sure what you're trying to accomplish, but.../

    > template <class T>
    > PtrTypeCleanup<T>::ptrTypeCleanup(T*& ptr)
    > : m_ptr(NULL)
    > {
    > // Most types have their assignment operator hidden.
    > // Cast so that we can set the bastard to NULL.
    > reinterpret_cast<void*>(m_ptr) = reinterpret_cast<void*>(ptr);


    This shouldn't compile. The result of a reinterpret_cast is an
    rvalue, and the left hand operand of the built-in assignment
    operator requires an lvalue.

    > }


    > template <class T>
    > PtrTypeCleanup<T>::~PtrTypeCleanup(void)
    > {
    > if(m_ptr)
    > {
    > // We must delete through the type
    > delete m_ptr;
    > // Most types have their assignment operator hidden.
    > // Cast so that we can set the bastard to NULL.
    > // void* p = reinterpret_cast<void*>(m_ptr);
    > // p = NULL;
    > }
    > }


    > template <class T>
    > void PtrTypeCleanup<T>::Release(void)
    > {
    > // Most types have their assignment operator hidden.
    > // Cast so that we can set the bastard to NULL.
    > // void* p = reinterpret_cast<void*>(m_ptr);
    > // p = NULL;
    > }


    > template <class T>
    > T*& PtrTypeCleanup<T>::eek:perator=(const T*& rhs)
    > {
    > // No self assignment
    > if(this == &rhs) { return *this; }
    >
    > reinterpret_cast<void*>(m_ptr) = reinterpret_cast<void*>(rhs.m_ptr);
    > }


    Can we see the complete definition of PtrTypeCleanup, and
    possibly an example of its use? As it is, I'm not quite clear
    what it is supposed to be doing. (Something like
    boost::scoped_ptr, but with an additional level of indirection
    on the pointer?)

    --
    James Kanze
     
    James Kanze, Jul 9, 2010
    #5
  6. Jeffrey Walton

    James Kanze Guest

    On Jul 8, 10:48 pm, Jeffrey Walton <> wrote:
    > On Jul 8, 4:52 pm, Victor Bazarov <> wrote:> On 7/8/2010 4:23 PM, Jeffrey Walton wrote:


    [...]
    > Here's how this might be used:


    > CSomeClass* someClass = new someClass;
    > PtrTypeCleanup<CSomeClass> cleanup(someClass);


    And you want the destructor of cleanup to delete the object?
    And maybe clear the pointer. What's wrong with simply:

    template<typename T>
    class PtrTypeCleanup : boost::noncopiable
    {
    T*& m_watched;
    public:
    explicit PtrTypeCleanup(T* clientPtr)
    : m_watched(clientPtr) {}
    ~PtrTypeCleanup()
    {
    delete m_watched;
    m_watched = NULL; // If desired.
    }
    };

    > // Do useful things with someClass. Upon an exception,
    > // I'm ensured the class is cleaned up. I'm also ensured
    > // that the original pointer is NULL in an attempt to
    > // vet pointer reuse.


    > Recall from my statement above, CSomeClass might (and probably does)
    > have a hidden operator=.


    What CSomeClass has is pretty much irrelevant here (although
    mostly objects that you allocation dynamically don't support
    assignment).

    --
    James Kanze
     
    James Kanze, Jul 9, 2010
    #6
  7. Jeffrey Walton

    Jorgen Grahn Guest

    On Thu, 2010-07-08, Jeffrey Walton wrote:

    > On Jul 8, 4:52 pm, Victor Bazarov <> wrote:

    ....
    >> Please see FAQ 5.8.

    > I cringe when I have to do anything with this solution. There are
    > nearly 900 source files which produce 7 executable modules with
    > everything inter-twinded. I probably could not give you a concrete
    > example without including at least 20 source files.


    I think he expects you to edit it down as needed, not just show a
    subset of your solution's files verbatim.

    > Do you really need concrete examples that compile and link for an
    > abstract question? Ie, why do I need an operator= when I'm dealing
    > with pointers.


    I suspect that he suspect that you are focusing on the wrong thing,
    and that your problem is in the parts you're not showing. Half the
    questions posted here these days are like that.

    And also your question is based on an impossible premise. You *don't*
    need Foo::eek:perator=() if all you do is mess with Foo pointers. All you
    need is, I think, the single forward declaration "class Foo;".

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Jul 20, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roxanne
    Replies:
    0
    Views:
    1,237
    Roxanne
    Jul 4, 2003
  2. Peter
    Replies:
    0
    Views:
    16,929
    Peter
    Jul 11, 2003
  3. =?Utf-8?B?QmlsbA==?=
    Replies:
    0
    Views:
    449
    =?Utf-8?B?QmlsbA==?=
    Apr 10, 2005
  4. Adam Knight
    Replies:
    1
    Views:
    1,129
    Ken Cox - Microsoft MVP
    Dec 5, 2005
  5. Achim Domma (SyynX Solutions GmbH)
    Replies:
    0
    Views:
    2,257
    Achim Domma (SyynX Solutions GmbH)
    Mar 6, 2006
Loading...

Share This Page