类实例化语法

Class instantiation syntax

本文关键字:语法 实例化      更新时间:2023-10-16

我一直被教导

1. Class c(arg);

2. Class c = arg;

是两个完全等价的语句,但看看这种情况。

#include <iostream>
class Intermediary {
};
class Left {
  public:
    Left(const Intermediary &) {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }   
};
class Right {
  public:
    // The argument is there just so that the example can work, see below
    Right(int) { 
        std::cout << __PRETTY_FUNCTION__  << std::endl;
    }
    operator Intermediary () const {
        std::cout << __PRETTY_FUNCTION__  << std::endl;
        return Intermediary();    
    }
};

现在,如果我这样做:

Left l = Right(0);

编译器将抱怨

error: conversion from Right to non-scalar type Left requested

但如果我这样做:

Left l(Right(0)); 

然后一切都编译了,输出就是

Right::Right(int)
Right::operator Intermediary() const
Left::Left(const Intermediary&)

然而,如果我这样做:

Left l = (Intermediary)Right(0);

然后所有内容都重新编译,输出与上面的一样。

很明显

1. Class c(arg);

2. Class c = arg;

不一样,但为什么不一样,有什么区别?我在网上找不到这方面的任何信息。

我一直被教导Class c(arg);Class c = arg;是两个完全等价的语句,但看看这种情况。

事实证明,它们并不等价。第一个从arg构造Class c,而第二个从arg构造Class,然后从中复制构造Class c。请注意,该实现允许省略该副本,而且通常是这样。

Left l = Right(0);

这需要从RightIntermediary的转换,以及从IntermediaryLeft的转换。这两个顺序的用户定义转换是标准不允许的,您必须像使用一样至少显式地执行其中一个转换:

Left l = (Intermediary)Right(0);