【问题标题】:One argument constructor and assignment operator一个参数构造函数和赋值运算符
【发布时间】:2014-09-15 15:52:06
【问题描述】:

考虑以下代码:

#include <iostream>
using namespace std;

class A{

private:
    int a;
public:
    A(int);
    void print();
    void operator =(int);
};

// One argument constructor
A::A(int b){
    cout<<"Inside one argument constructor"<<endl;
    this->a=b;
}

void A:: operator =(int b){
    cout<<"Inside operator function"<<endl;
    this->a = b;
}

void A::print(){
    cout<<"Value of a ="<<a<<endl;
}

int main() {

    /* INITIALIZATION */
    A obj1=2;
    obj1.print();

    /* ASSIGNMENT */
    obj1=3;
    obj1.print();

    return 0;
}

上面代码的输出可以在这里看到:http://ideone.com/0hnZUb。它是:

Inside one argument constructor
Value of a =2
Inside operator function
Value of a =3

所以我观察到的是,在初始化期间,调用了单参数构造函数,但在赋值期间,调用了重载的赋值运算符函数。这种行为是由 C++ 标准强制执行的,还是特定于编译器的?任何人都可以引用标准中定义此行为的部分吗?

【问题讨论】:

  • 这是标准行为,你期待什么?
  • 您观察到在构造过程中调用了构造函数,在赋值过程中调用了赋值运算符。
  • 请记住,符号在声明中具有不同的含义;该声明中的= 不是运算符,它是指定初始化程序的语法的一部分。

标签: c++


【解决方案1】:

这是标准行为。

我搜索了最新的 C++ 标准,ISO/IEC 14882:2011(E),Programming Language C++。

以下代码

A obj1 = 2;

是一个初始化。它在第 8.5 节初始化程序第 16 节中进行了描述。

16 初始化器的语义如下。目标类型是正在初始化的对象或引用的类型,源类型是初始化表达式的类型。如果初始化器不是单个(可能是带括号的)表达式,则源类型未定义。

此子句的以下部分很长。我只参考与您的示例代码相关的内容。

——如果目标类型是(可能是 cv 限定的)类类型:

- 如果初始化是直接初始化,或者如果是复制初始化,其中源类型的 cv 非限定版本与目标类相同或派生类,则考虑构造函数.枚举适用的构造函数(13.3.1.3),并通过重载决议(13.3)选择最佳构造函数。调用如此选择的构造函数来初始化对象,使用初始化表达式或表达式列表作为其参数。如果没有构造函数适用,或者重载解决方案不明确,则初始化格式错误。

第 13.3.1.3 节是构造函数的初始化。

根据8.5和13.3.1.3,构造函数

A(int);

选择初始化obj1。


至于第二个

obj1 = 3;

此行为由 5.17 赋值和复合赋值运算符第 4 节定义。

4 如果左操作数是类类型,则类应该是完整的。对类对象的赋值由复制/移动赋值运算符(12.8、13.5.3)定义。

13.5.3 赋值,第 1 条。

1 赋值运算符应该由一个只有一个参数的非静态成员函数来实现。因为复制赋值运算符 operator= 如果未由用户声明,则为类隐式声明(12.8),因此基类赋值运算符始终被派生类的复制赋值运算符隐藏。

功能

void operator =(int);

被选中

obj1 = 3;

根据重载规则。

【讨论】:

    【解决方案2】:

    这是标准的,我想构造函数用于初始化,而赋值运算符用于赋值也就不足为奇了。在 C++ 标准中,第 12.8 节 - 复制和移动类对象 - 以

    开头

    可以通过两种方式复制或移动类对象:通过初始化(12.1、8.5),包括用于函数参数传递(5.2.2)和用于函数值返回(6.6.3);并通过分配(5.17)。从概念上讲,这两个操作是由复制/移动构造函数 (12.1) 和复制/移动赋值运算符 (13.5.3) 实现的。

    【讨论】:

      猜你喜欢
      • 2011-02-20
      • 2011-07-19
      • 1970-01-01
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      • 2014-02-17
      相关资源
      最近更新 更多