C ++:指针数据成员在const上下文中的奇怪行为

时间:2011-10-16 10:11:27

标签: c++ pointers const

方法上的const限定符应该保护数据成员不被错误覆盖。如果你有一个数据成员是一个指针,那么只有指针被保护,指向的值不是。它是C ++设计中的一个缺陷还是它有一些基本的东西?

这是一个演示这种情况的代码。在报告不相关的错误和风格问题之前,请考虑其唯一目的是证明上述情况并且简短明了。

#include <cstdio>
#include <cstdlib>
#include <cstring>

class Cat
{
public:
        Cat(char const *name)
        : _name(strdup(name))
        { }
        ~Cat(){ free(_name); }
        void SetName(char const *name)
        {
                free(_name);
                _name = strdup(name);
        }
        char const* GetName() const
        {
                _name[0] = 'P';
                return _name;
        }
private:
        char *_name;
};

int main()
{
        Cat c("lost+found");
        c.SetName("Molly");
        printf("%s\n",c.GetName());
        return 0;
}

使用以下命令编译没有警告和错误:

g++ -W -Wall -Wextra -pedantic -Os pmc.cpp -o pmc

结果程序的输出为Polly

更新使用迂腐char const *代替传统const char *

3 个答案:

答案 0 :(得分:5)

这里提供的基本要素只是清晰度。指针是类的成员,它的指针不是:当类也没有自动构造时,它既不会自动被破坏。它可能是一个完全不同的对象,因此当类变为const时,它不一定是const。

你在这里需要像std :: string这样的东西,也就是指针的附加语义 - 例如保证它的内容不会在你的类之外发生变化。

答案 1 :(得分:3)

  

一个方法的const限定符,用于保护数据成员不被错误覆盖。如果你有一个数据成员是一个指针,那么只有指针被保护,指向的值不是。

您对const限定符的目的有误解。它有三个目的:

  • 某个类的const限定实例只能调用该类的const限定成员函数。在const限定实例的情况下,禁止调用非const限定的成员函数。
  • const限定的成员函数无法更改实例的直接内容。指向实例外部数据的内容不是实例的直接内容的一部分;它们根本不受const限定符的保护。
  • 基于上述内容,编译器可以使用大量优化方法。

const限定词并不能保护你,因为某些职业的作者不会在你的脚下(或更高)射击自己。它所做的是保护你作为某个类的作者,防止其他人对你的类造成损害,并且它允许编译器通过几个非const设置中不可用的优化进入城镇。

答案 2 :(得分:2)

const成员函数中,_name的类型变为char * const,这意味着它是const的指针,而不是指针所指向的数据。

您似乎认为_name变为const char*。不,const适用于pointer,而不适用于它指向的数据。因此_name必须成为char * const

为了尽量减少这种混淆,我更喜欢语法T const而不是const T,尽管两者完全相同。因为如果Tchar*,则T const将成为char * const,而const T将成为const char*。虽然前者有助于理解,但后者变得复杂。