C中的临时,参考和三元运算符

前端之家收集整理的这篇文章主要介绍了C中的临时,参考和三元运算符前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下基本代码
struct X {
  X(const char* descr) {...}
  ~X() {...} // Not virtual
  virtual void foo() const {...}
};

struct Y : public X {
  Y(const char* descr) {...}
  ~Y() {...} // Not virtual
  virtual void foo() const {...}
};


const X& factory() {
    static X sampleX{"staticX"};
    static Y sampleY{"staticY"};
    return X or Y depending of the test case;
};

4个测试用例:

只是Y =好的

const X& var = Y{"temporaryY"};
var.foo();

结果:

X::X() // base temporaryY
Y::Y() // temporaryY
Y::foo()
Y::~Y() // temporaryY
X::~X() // base temporaryY

只是X =好的

const X& var = X{"temporaryX"};
var.foo();

结果:

X::X() // temporaryX
X::foo()
X::~X() // temporaryX

Y或X via function = OK

const X& var = factory();
var.foo();

结果:

X::X() // staticX
X::X() // base staticY
Y::Y() // staticY
X::foo() or Y::foo()
Y::~Y() // staticY
X::~X() // base staticY
X::~X() // staticX

Y或X通过三元运算符= WTF ?!

const X& var = false ? X{"temporaryX"} : Y{"temporaryY"};
var.foo();

结果:

X::X() // base temporaryY
Y::Y() // temporaryY
Y::~Y() // temporaryY
X::~X() // base temporaryY
X::foo()
X::~X() // base temporaryY

有人可以解释为什么七个地狱:

>在范围结束之前调用Y的析构函数
> X :: foo()被调用而不是Y :: foo()?
> X的析构函数运行两次?

解决方法

你缺少的是你的临时Y正在通过切片复制构造成一个隐藏的临时X,它绑定到你的const引用.那就是你看到的最终析构函数,也解释了为什么Y比预期更早被破坏.这个副本的原因是三元运算符的“返回”只是一种类型. X不可能被视为Y,因此X是要使用的常见类型,从而引起额外的临时X对象.

请注意,这与“Just Y”测试用例不同,因为在该实例中创建了Y临时,然后立即尝试绑定到const X&这是允许的.在三元情况下,运算符本身会引入运算符操作数的公共对象类型的中间切片,在本例中为X.

我相信你可以通过转换为父引用来避免临时切片,但是我没有访问C 11编译器来测试它(除了问题中有些不完整的代码):

const X& var = false ? X{"temporaryX"} : static_cast<const X&>(Y{"temporaryY"});

猜你在找的C&C++相关文章