关于函数作为指针的返回类型的困惑

时间:2020-08-14 17:43:22

标签: c++ pointers return-value

我编写了以下代码:

#include <iostream>
using namespace std;

const int * myFunction()
{
    int * p = new int(5);
    return p;
}
 
int main()
{
    int * q = myFunction();
    cout << "*q=" << *q;
    cout << endl;
    return 0;
}

我故意编写以上代码以接收错误。我犯的错误是我将函数myFunction()的返回类型表示为const int *,但是当我在myFunction()中调用main()时,指针变量q却没有声明为constmyFunction()的返回类型必须与将要接收其返回值的变量类型完全匹配(我在这里正确吗?这是我所了解的)。

因此,我通过将第11行更正为const int * q = myFunction();来解决了该错误。现在,(指针)变量q的类型为const int *,与返回类型myFunction()完全匹配,并且编译的代码没有错误,产生的输出为*q=5 (到目前为止,我的理解是正确的吗?)。

然后,我编写了以下代码:

#include <iostream>
using namespace std;

const int * const myFunction()
{
    int * p = new int(5);
    cout << "p: " << p;
    return p;
}
 
int main()
{
    int a;
    const int * q = myFunction();
    cout << "\nq=" << q;
    cout << "\n*q=" << *q;
    delete q;
    q = &a;
    cout << "\nq: " << q;
    cout << endl;
    return 0;
}

我也期望在这里出现错误。因为现在myFunction()的返回类型为const int * const,但是(指针)变量q的类型为const int *q未声明为常量指针。但是程序已编译,我得到的输出如下:

p: 0x36cb8
q=0x36cb8
*q=5
q: 0x61ff08

我很困惑第二个代码为什么要编译和运行。我以为是谁将从myFunction()那里获得返回值,应该总是照顾它(即不能允许它使用不同的内存地址),但是指针变量q却采用了不同的方法内存位置。

2 个答案:

答案 0 :(得分:3)

myFunction的返回类型必须与要接收其返回值的变量类型完全匹配。 (我在这里正确吗?这是我所了解的。)

否,返回类型必须与变量类型不完全匹配。但是必须可以将返回类型隐式转换为变量的类型。 例如,将编译如下内容:

int someInt = getMeAFloat();

如果getMeAFloat返回float,则会编译该文件,因为可以将float隐式转换为int。 (请注意,这会给您一个警告,并且是不好的,因为您会丢失float的额外信息,但是我只是想说明我的观点)

您的第一个示例无法编译,因为通常无法将const int*转换为int*

正如user4581301所指出的,第二个示例中的第二个const无关紧要,因为只有返回的指针值被分配给了主函数中的指针。第二个const使指针本身恒定,这对值没有影响。 这意味着const int * const myFunction()等于const int * myFunction()

答案 1 :(得分:2)

在第二个代码中,qconst int *-非常量“指向const int的指针”。由于q本身不是const,因此可以重新分配它以指向新地址。

编译器允许q = &a;,因为可以将{{1}分配给{{1}(即int*&a以来返回的a) }}。换句话说,可以将“指向非const数据的指针”分配给“指向const数据的指针”,从而有效地对以其他方式可写的数据进行只读访问。

反之则不成立-无法将“指向const数据的指针”分配给“指向非const数据的指针”,因为这将允许对只读数据进行可写访问-这就是为什么第一个代码无法执行编译。