我正在研究一个项目,在玩这些代码时,我遇到了以下特殊情况。
我有两节课。第一个在表示笛卡尔坐标的数组中包含三个浮点数,并定义了获取这些点的方法;
class foo
{
protected:
float m_Coordinates[3];
public:
foo(float coordinates[3]);
void GetPoints(int resultArray[]);
};
foo::foo(int coordinates[3])
{
std::copy(coordinates, coordinates+3, m_Coordinates);
}
void foo::GetPoints(float resultArray[])
{
std::copy(m_Coordinates, m_Coordinates+3, resultArray);
}
第二个类也存储一个浮点数组,但是它的构造函数使用foo作为包装类来传递值:
class bar
{
protected:
float m_MoreCoordinates[3];
public:
bar(foo f);
};
bar::bar(foo f)
{
f.GetPoints(m_MoreCoordinates);
//m_MoreCoordinates is passed by reference, so the values in
//m_MoreCoordinates are equal to the values in f.m_Coordinates
//after this line executes
}
请忽略这样一个事实,即我对此代码所采用的方法非常糟糕。它最初是一个使用数组的实验。将它们作为参数传递,将它们作为返回类型等。
行。这是我注意到奇怪的地方。如果我声明一个浮点数组并将它们作为参数传递给bar的构造函数,编译器将生成一个类foo的实例并将其传递给bar。请参阅下面的示例代码:
int main(int argv, char** argc)
{
float coordinates[] = {1.0f, 2.1f, 3.0f};
//Here the compiler creates an instance of class foo and passes
//coordinates as the argument to the constructor. It then passes
//the resulting class to bar's constructor.
bar* b = new bar(coordinates);
//Effectively, the compiler turns the previous line into
//bar* b = new bar(foo(coordinates));
return 0;
}
当我看到这个时,我认为它是代码的一个非常简洁的功能,并且想知道它是如何以及为什么发生的。这样做安全吗?我不明白它是如何工作的,所以我不想依赖它。如果有人能解释这是如何运作的,我真的很感激。
修改 感谢Mankarse指出如何在主要中执行转换。最初,我有:
//Effectively, the compiler turns the previous line into
//bar* b = new bar(*(new foo(coordinates)));
答案 0 :(得分:2)
正如您所猜测的,编译器隐式创建了一个foo
对象并将其传递给bar
。通常,这被认为有点危险,因为foo
在没有知识的情况下构建,为避免这种情况,您可以将foo
构造函数声明为explicit
。在这种情况下,编译器不会从浮点数组中隐式创建foo
,您将收到编译器错误。
答案 1 :(得分:1)
当你考虑它时,你会一直使用它。请考虑以下事项:
void foo(std::string argument);
然后,假设您使用字符串文字调用此函数:
foo("argument");
这与:
相同std::string argument("argument");
foo(argument);
这是一个非常有用的功能。