类实例化语法

时间:2011-10-29 00:49:40

标签: c++ constructor instantiation standards parentheses

我一直都被教导

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;

不一样,但为什么不呢,有什么区别?我在网上找不到任何关于此的信息。

1 个答案:

答案 0 :(得分:5)

  

我一直被告知Class c(arg);Class c = arg;是两个完全等同的陈述,但请看这种情况。

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

Left l = Right(0);

这需要从Right转换为Intermediary,从Intermediary转换为Left。标准不允许这两个顺序的用户定义转换,您必须至少执行其中一个明确的操作:

Left l = (Intermediary)Right(0);