我最近重构了这样的代码(MyClass
到MyClassR
)。
#include <iostream>
class SomeMember
{
public:
double m_value;
SomeMember() : m_value(0) {}
SomeMember(int a) : m_value(a) {}
SomeMember(int a, int b)
: m_value(static_cast<double>(a) / 3.14159 +
static_cast<double>(b) / 2.71828)
{}
};
class MyClass
{
public:
SomeMember m_first, m_second, m_third;
MyClass(const bool isUp, const int x, const int y)
{
if (isUp)
{
m_first = SomeMember(x);
m_second = SomeMember(y);
m_third = SomeMember(x, y);
}
else
{
m_first = SomeMember(y);
m_second = SomeMember(x);
m_third = SomeMember(y, x);
}
}
};
class MyClassR
{
public:
SomeMember m_first, m_second, m_third;
MyClassR(const bool isUp, const int x, const int y)
: m_first(isUp ? x : y)
, m_second(isUp ? y : x)
, m_third(isUp ? x, y : y, x)
{
}
};
int main()
{
MyClass a(true, 1, 2);
MyClassR b(true, 1, 2);
using namespace std;
cout.precision(10);
cout
<< "a:" << endl
<< "\tfirst: " << a.m_first.m_value
<< "\tsecond: " << a.m_second.m_value
<< "\tthird: " << a.m_third.m_value << endl;
cout
<< "b:" << endl
<< "\tfirst: " << b.m_first.m_value
<< "\tsecond: " << b.m_second.m_value
<< "\tthird: " << b.m_third.m_value << endl;
return 0;
}
我(假设)我已经拥有了所有这些答案,但我认为这是分享的有趣问题。
更新
扩展代码,因此它可以“复制和粘贴并执行”。 VC9没有给我任何投诉,所以 VC6不是问题。
为完整起见,输出为:
a:
first: 1 second: 2 third: 1.054069532
b:
first: 1 second: 2 third: 1.004499999
答案 0 :(得分:8)
我不确定你到底想要什么,但让我们开始......
首先,沟渠VC6。 认真。使用它是一个很大的问题,因为它不符合标准,排除了很多选择。正确使用它就像玩俄罗斯轮盘赌。
m_third
的构造函数不符合您的想法。你不能写这样的条件表达式:“几个参数”在C ++中不是有效的表达式,条件运算符用于表达式。
代码编译因为它仍然正确,它只是没有按你想要的那样做。它不是使用“几个参数”,而是评估序列点运算符(,
),它只取表达式的 last 值,因此您的条件实际上等效于:{{1} }
正确的方法是使用两个条件:isUp ? y : x
m_third(isUp ? x : y, isUp ? y : x)
的第三个构造函数错误,值可能溢出,产生负值 - 我非常怀疑这就是你想要的。
答案 1 :(得分:2)
m_third(isUp ? x, y : y, x)
这看起来不错。第一个x
是无意义的表达,因为它没有副作用且结果未被使用,那么:
的两边具有相同的值和副作用,因此?:
可以是被消除为?
之前的表达也没有副作用。
m_third(y, x)
但现在它没有做原始代码所做的......这是错误吗?
答案 2 :(得分:0)
错误是什么 这样做的正确方法是什么?
我猜你的目的是展示逗号运算符与三元组合的一些天真用法?也许隐藏了一些聪明且意想不到的运算符优先级,但我认为代码绝对是人为的。如果这是重点,那么我认为“正确的做法”就是不使用C ++或在使用之前先学习它。是的,它有许多可能看起来像“怪癖”的结构,你可以创建许多编译器接受的奇怪的代码。通过使用C ++,我会说你被认为知道这些工具。
为什么要编译
因为它不包含任何错误,并且它是一个没有歧义的正确C ++代码。