简体   繁体   中英

C++ Overload Operator = for Pointers does not work/compile properly

I am trying to implement a template Class with an Operator Overload for = so far it works for non pointer elements. For Pointer Elements it doesn't work exactly as I expect it to, so my question is why this is sow and how do I force c++ do it as I want.

My template Class:

template <class T>
class IBag {
public:
    T _val;
    void Set(T val) { _val = val; } 
    T Get() { return _val; }

    IBag& operator=(T val) {
        this->Set(val);
        return *this;
    }

    operator T() {
        return this->Get();
    }
};

How it works using the IBag Class:

class IBagExample
{
   void showExample() {
        IBag<QString*> pbag;
        pbag = new QString("Blub"); // This works !
    }
};

how it does not compile:

class IBagExample
{
   void showExample() {
        IBag<QString*> pbag = new QString("Blub"); // This doesn't compile !
    }
};

The compiler Error I get is :

error: no viable conversion from 'QString *' to 'IBag<QString *>'
    IBag<QString*> pbag2 = new QString("Blub");
                   ^       ~~~~~~~~~~~~~~~~~~~

For me it seems the same, maybe I need to tell the compiler something to understand what type of pointer is now going to be pushed into the pbag. But I have no Idea how to do that.

Using the operator overload like

IBag<QString*> pbag; pbag = new QString("Blub"); // This does compile !

seems just ridiculous.

(Note:The IBag example is just a simplification of the Code I am trying to implement.)

Thanks a lot,

IBag<QString*> pbag = new QString("Blub");

This doesn't actually call the assignment operator, it calls a constructor. You need to define that something like:

template <class T>
class IBag {
public:
    IBag( const IBag& rhs )
    {
        // ....
    }

};

or:

    IBag( const T& rhs )
    {
        // ....
    }

Assignment is not construction. A copy assignment operator doesn't handle construction (even if the = in an assignment looks suspiciously like the = in a declaration with copy initialization). Either define a suitable constructor or use C++11 braces initialization, eg

auto pbag2 = IBag<QString*>{ new QString("Blub") };

Disclaimer: code untouched by compiler's hands.


Issues with the code:

  • setters and getters are in general a design smell, a Java-ism, even if they sometimes are useful,

  • public data members are also a design smell for a class with an invariant (such as non-null pointers),

  • a public data member with a setter and a getter, that's not meaningful,

  • you need to take charge of copying (rule of three, rule of zero), and

  • you need to make a decision on supporting constness, and do The Right Thing™ (whatever it may be).


For a logical interface, as this is, also consider adding a virtual destructor. That enables RTTI via the interface. Eg deleting an object via the interface, or dynamic casting to some other interface or implementation class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM