理解C ++中const值的const指针

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了理解C ++中const值的const指针相关的知识,希望对你有一定的参考价值。

我有两个问题。

首先,我对const const指针的理解有一点问题。我不明白为什么B::insert工作,而C::insert导致编译器错误。我的意思是,C中的列表不完全等于C::insert的参数吗?

我的第二个问题是A const * const a是否也可以写为const A& a

class A
{
    //Do stuff
};

class B 
{
private:
    list<A const *> l;

public:
    void insert(A const * const a)
    {
        l.push_back(a);
    }
};

class C 
{
private:
    list<A const * const> l;

public:
    void insert(A const * const a)
    {
            l.push_back(a);
    }
};

编辑(编译错误):

g++ -Wall  -c  -O2 "sonnensystem.cpp" -std=c++11 (im Verzeichnis: C:UsersKenanDesktopOPRcppcodeKonzepteKapselungArchitektursonnensystem01)
In file included from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33:0,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/allocator.h:46,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/string:41,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/locale_classes.h:40,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/ios_base.h:41,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ios:42,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ostream:38,
             from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/iostream:39,
             from sonnensystem.cpp:1:
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h: In instantiation of 'struct __gnu_cxx::new_allocator<const A* const>':
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/allocator.h:92:11:   required from 'class std::allocator<const A* const>'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/stl_list.h:315:9:   required from 'class std::__cxx11::_List_base<const A* const, std::allocator<const A* const> >'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/stl_list.h:507:11:   required from 'class std::__cxx11::list<const A* const>'
sonnensystem.cpp:28:27:   required from here
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h:93:7: error: 'const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const A* const; __gnu_cxx::new_allocator<_Tp>::const_pointer = const A* const*; __gnu_cxx::new_allocator<_Tp>::const_reference = const A* const&]' cannot be overloaded
       address(const_reference __x) const _GLIBCXX_NOEXCEPT
       ^
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h:89:7: error: with '_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = const A* const; __gnu_cxx::new_allocator<_Tp>::pointer = const A* const*; __gnu_cxx::new_allocator<_Tp>::reference = const A* const&]'
       address(reference __x) const _GLIBCXX_NOEXCEPT
       ^
Kompilierung fehlgeschlagen.
答案

在你的声明A const * const中,第一个constA *指针指向一个无法改变的值(一个const指针)。第二个const说,该指针的值不能改变,就像const int无法改变。由于list(和其他标准容器)要求其成员可分配,因此它们不能是const值。

对于你的第二个问题,A const * constconst A&是相似的,但不可互换,因为你使用它们的方式是不同的。

另一答案

当使用std::list<T>时,T的一个要求是它是CopyAssignable。见http://en.cppreference.com/w/cpp/container/list

使用const类型作为参数时,不满足该要求。如果使用的话,您将看到类似的错误(如果不是相同的错误):

std::list<const int> a;
a.push_back(10);

无论如何,

list<A const * const> l;

不可用。

另一答案

A const * constA const &之间唯一真正的区别是,更容易检查指针是无效的(你可以将一个指针指向A,然后取消引用以获得一个空的A引用,它更容易去if(!a))。

C::insert案例是由于代码试图分配给内部节点值。如果你使用emplace_back而不是push_back,它可能会工作。

以上是关于理解C ++中const值的const指针的主要内容,如果未能解决你的问题,请参考以下文章

c语法将const指针传递给const数据到函数

C++中的const关键字深入理解(关于引用指针顶层const)

const关键字与指针

C#中const用法详解

C/C++中const关键字详解

C 语言const 关键字用法 ( 常量指针 - const 在 * 左边 - 修饰数据类型 - 内存不变 | 指针常量 - const 在 * 右边 - 修饰变量 - 指针不变 )