在C ++中作为参数传递时,数组隐式转换为容器类

时间:2012-02-18 04:16:54

标签: c++ arrays constructor instantiation implicit

我正在研究一个项目,在玩这些代码时,我遇到了以下特殊情况。

我有两节课。第一个在表示笛卡尔坐标的数组中包含三个浮点数,并定义了获取这些点的方法;

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)));

2 个答案:

答案 0 :(得分:2)

正如您所猜测的,编译器隐式创建了一个foo对象并将其传递给bar。通常,这被认为有点危险,因为foo在没有知识的情况下构建,为避免这种情况,您可以将foo构造函数声明为explicit。在这种情况下,编译器不会从浮点数组中隐式创建foo,您将收到编译器错误。

答案 1 :(得分:1)

当你考虑它时,你会一直使用它。请考虑以下事项:

void foo(std::string argument);

然后,假设您使用字符串文字调用此函数:

foo("argument");

这与:

相同
std::string argument("argument");
foo(argument);

这是一个非常有用的功能。