处理类和赋值运算符

Handle class and assignment operator

本文关键字:赋值运算符 处理      更新时间:2023-10-16

我有一个简单的句柄类,用来控制继承类的对象。下面是简单的实现:

#include <iostream>
class ParametersInner
{
  public:
    ParametersInner() {}
    virtual ~ParametersInner() {}
    virtual ParametersInner *clone() const = 0;
};
class ParametersConstant : public ParametersInner
{
  public:
    ParametersConstant(){};
    virtual ParametersInner *clone() const { return new ParametersConstant(*this); }
};
class Parameters
{
  public:
    Parameters(const ParametersInner &innerObject)
    {
        std::cout << "CC (and implicit conversion)n";
        InnerObjectPtr = innerObject.clone();
    }
    Parameters(const Parameters &original)
    {
        std::cout << "CCn";
        InnerObjectPtr = original.InnerObjectPtr->clone();
    }
    Parameters &operator=(const Parameters &original)
    {
        std::cout << "AOn";
        if (this != &original)
        {
            delete InnerObjectPtr;
            InnerObjectPtr = original.InnerObjectPtr->clone();
        }
        return *this;
    }
    virtual ~Parameters() { delete InnerObjectPtr; }
  private:
    ParametersInner *InnerObjectPtr;
};
int main()
{
    ParametersConstant VolParam;
    ///this is identical to (Parameters)VolParam so it calls the copy constructor. But why does it not call the assignment operator = afterwards?
    Parameters Vol = VolParam;
    ///calls copy constructor - OK
    Parameters Vol_0(Vol);
    ///calls assignment operator - OK
    Vol_0 = Vol;
    return 0;
}

代码相当简单,但有一个方面我无法弄清楚,这与行Parameters Vol = VolParam;有关。据我了解,基本上这一行翻译成的是Parameters Vol = (Parameters)VolParam;,即有一个类型转换。

但是,转换后为什么不调用赋值运算符?Vol还如何创建?

你可以写

Parameters Vol = VolParam;

因为这是我们在 C(int i = 0; 中所做的方式),但除非你在类声明中付出额外的努力(使用 explicit 个构造函数),否则效果与

Parameters Vol(VolParam);

尽管使用了=令牌,但这不是分配。

没有类型名称的Vol = VolParam;是一个赋值。

行参数Vol = VolParam;。据我了解,基本上这一行翻译成的是参数Vol = (Parameters)VolParam;,即有一个类型转换。

但是,转换后为什么不调用赋值运算符?Vol 还是如何创建的?

它不是赋值或类型转换,而是隐式构造。
这是构造函数声明,它允许:

Parameters(const ParametersInner &innerObject)
{
    std::cout << "CC (and implicit conversion)n";
    InnerObjectPtr = innerObject.clone();
}

若要防止这种情况,请将 explicit 关键字与构造函数声明一起使用。