const正确性和返回值-C ++ [英] const correctness and return values - C++

查看:133
本文介绍了const正确性和返回值-C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码。

struct foo
{
};

template<typename T>
class test
{
public:   

    test() {} 

    const T& value() const
    {
        return f;
    }

private:
    T f;
};


int main()
{
    const test<foo*> t;
    foo* f = t.value();
    return 0;
}

t const 变量和 value()是一个常量成员函数,它返回 const T& 。 AFAIK不能将 const 类型分配给非const类型。但是 foo * f = t.value(); 的编译方式很好。这是怎么回事,如何确保 value()仅可以分配给 const foo *

t is a const variable and value() is a constant member-function which returns const T&. AFAIK, a const type is not assignable to a non-const type. But how foo* f = t.value(); compiles well. How this is happening and how can I ensure value() can be only assigned to const foo*?

编辑

我发现,这是在使用模板时发生的。以下代码按预期工作。

I found that, this is happening on when templates are used. Following code works as expected.

class test
{
public:   

    test() {} 

    const foo* value() const { return f; }

private:
    foo* f;
};


int main()
{
    const test t;
    foo* f = t.value(); // error here
    return 0;
}

为什么使用模板时出现问题?

Why the problem is happening when templates are used?

推荐答案

因为您有两个间接级别-在您的主函数中,调用 value 返回指向非常量 foo 的const指针的引用。

Because you have two levels of indirection - in your main function, that call to value returns a reference to a const pointer to a non-const foo.

这可以安全地复制到非常量中指向非常量 foo 的指针。

This can safely be copied into non-const pointer to a non-const foo.

如果要实例化 test const foo * ,情况将有所不同。

If you'd instantiated test with const foo *, it would be a different story.

const test<const foo*> t;
foo* f = t.value(); // error
const foo* f = t.value(); // fine
return 0;

更新

从注释:


value()返回const T&只能将
分配给另一个const
类型。但是在这种情况下,编译器可以安全地允许
进行转换。

value() returns const T& which can only be assigned to another const type. But in this case, compiler is safely allowing the conversion.

只能读取常量数据。它不能被写入(变异)。但是复制一些数据是一种读取数据的方式,因此可以。例如:

Const data can only be read. It cannot be written ("mutated"). But copying some data is a way of reading it, so it's okay. For example:

const int c = 5;
int n = c;

在这里,我在 c ,然后将数据复制到非常量变量n中。很好,它只是读取数据。 c 中的值尚未修改。

Here, I had some const data in c, and I copied the data into a non-const variable n. That's fine, it's just reading the data. The value in c has not been modified.

现在,假设您的 foo 中包含一些数据:

Now, suppose your foo had some data in it:

struct foo { int n; };

如果我有指向其中一个的非常量指针,则可以修改 n 值通过指针。您要求您的 test 模板存储指向非常量 foo 的指针,然后创建一个 test 。因此,仅指针地址是恒定的。没有人可以在 test 内部更改存储在指针中的地址,因此无法使其指向另一个对象。但是,它指向的对象可以修改其内容。

If I have a non-const pointer to one of those, I can modify the n value through the pointer. You asked your test template to store a pointer to a non-const foo, and then made a const instance of test. Only the pointer address is constant, therefore. No one can change the address stored in the pointer inside test, so it cannot be made to point to another object. However, the object it points to can have its contents modified.

更新2:

制作示例的非模板版本时,您犯了一个错误。为正确起见,您需要将 foo * 替换为每个有 T 的地方。

When you made your non-template version of the example, you made a mistake. To get it right, you need to substitute foo * into each place where there's a T.

const T& value() const

请注意,您引用了const T 在那里。因此,返回值将引用const:a foo * 。这只是指针地址,无法修改。它指向的对象可以修改其内容。

Notice that you have a reference to a const T there. So the return value will be a reference to something const: a foo *. It's only the pointer address that can't be modified. The object it points to can have its contents modified.

在第二个示例中,您摆脱了引用部分,从而改变了含义并使 const 修饰符应用于指针所指向的对象,而不是应用于指针本身。

In your second example, you got rid of the reference part, which changes the meaning and makes the const modifier apply to the object that the pointer points to, instead of applying to the pointer itself.

这篇关于const正确性和返回值-C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆