指针的C++重载运算符=无法正常工作/编译

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

本文关键字:常工作 工作 编译 C++ 重载 运算符 指针      更新时间:2023-10-16

我正在尝试实现一个带有运算符重载的模板类=到目前为止,它适用于非指针元素。对于指针元素,它并没有像我期望的那样工作,所以我的问题是为什么这是sow,以及我如何强迫c++按照我的意愿来做。

我的模板类别:

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();
    }
};

如何使用IBag类:

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

如何不编译:

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

我得到的编译器错误是:

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

对我来说,这似乎是一样的,也许我需要告诉编译器一些事情,以了解什么类型的指针现在将被推入pbag。但我不知道该怎么做。

使用操作员过载,如

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

看起来很可笑。

(注意:IBag示例只是我试图实现的代码的简化。)

非常感谢,

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

这实际上并没有调用赋值运算符,而是调用构造函数。你需要定义这样的东西:

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

或:

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

赋值不是构造。复制赋值运算符不处理构造(即使赋值中的=看起来可疑地类似于带有复制初始化的声明中的=)。要么定义一个合适的构造函数,要么使用C++11大括号初始化,例如

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

免责声明:代码未经编译器处理。


代码问题:

  • setter和getter通常是一种设计气味,一种Java主义,即使它们有时很有用,

  • 公共数据成员也是具有不变量(如非空指针)的类的设计气味,

  • 一个带有setter和getter的公共数据成员,这没有意义,

  • 你需要负责复制(三规则,零规则)和

  • 你需要做出支持constness的决定,并做正确的事情™(不管是什么)。


对于逻辑接口,也可以考虑添加一个虚拟析构函数。这通过接口启用RTTI。例如,通过接口删除对象,或者动态转换为其他接口或实现类。