c ++ const成员函数,它返回一个const指针..但返回的指针是什么类型的const?

时间:2010-10-08 07:26:35

标签: c++ const

如果有人问过这个我道歉,但是如何在c ++中创建一个成员函数,它返回以下scenerios中的指针: 1.返回的指针是常量,但可以修改里面的垃圾。 2.里面的垃圾是常量但可以修改返回的指针。 3.垃圾和指针都不能被修改。

是这样的:

  1. int *const func() const
  2. const int* func() const
  3. const int * const func() const
  4. 我读过的所有教程都没有涵盖这种区别。

    旁注: 如果我的方法被声明为const,那么教程说我说我不会修改参数..但是在参数是指针的情况下,这对我来说还不够清楚。我的参数需要像:

    一个。 void func(const int* const x) const;
    void func(const int* x) const;
    C。 void func(const int* const x) const;

5 个答案:

答案 0 :(得分:65)

我不知道你读过哪本书,但是如果你标记一个方法const,则意味着this将是const MyClass*类型而不是MyClass*,这反过来又是mutable表示您不能更改未声明为this的非静态数据成员,也不能在int * const func () const上调用任何非const方法。

现在返回值。

1。 const

函数是常量,返回的指针是常量,但可以修改'junk inside'。但是,我认为返回一个const指针是没有意义的,因为最终的函数调用将是一个rvalue,而非类类型的rvalues不能是const,这意味着const int* func () const无论如何都会被忽略

2。 const int * const func() const

这是一件有用的事情。 “垃圾内部”无法修改

3。 {{1}}

由于1中的原因,

在语义上几乎与2相同。

HTH

答案 1 :(得分:14)

const的一些用法并没有多大意义。

假设您具有以下功能:

void myFunction (const int value);

const告诉编译器,函数内部的值不能改变。此信息对调用者没有任何价值。由函数本身决定如何处理该值。对于调用者,以下两个函数定义对他来说完全相同:

void myFunction (const int value);
void myFunction (int value);

因为值是按值传递的,这意味着函数无论如何都会获得本地副本。

另一方面,如果参数是引用或指针,事情会变得非常不同。

void myFunction (const MyClass &value);

这告诉调用者值是通过引用传递的(所以在屏幕后面它实际上是一个指针),但调用者承诺不会改变值。 指针也是如此:

void myFunction (const MyClass *value);

我们传递一个指向MyClass的指针(由于性能原因),但该函数承诺不会更改该值。

如果我们写下以下内容:

void myFunction (MyClass * const value);

然后我们回到第一个情况。 myFunction获取一个指针,该指针由值传递,并且是const。由于MyFunction获取指针值的副本,因此调用者是否为const并不重要。最重要的是myFunction可以改变值的内容,因为指针变量本身是const,但其中的内容不是。

返回值也是如此:

const double squareRoot(double d);

这没有任何意义。 squareRoot返回一个const double,但由于它是'by value'传递的,因此需要复制到我自己的局部变量,我可以用它做任何我想做的事。

另一方面:

const Customer *getCustomer(char *name);

告诉我getCustomer向我返回一个指向客户的指针,我不允许更改客户的内容。

实际上,最好还要生成char-pointer-contents const,因为我不希望函数改变给定的字符串:

const Customer *getCustomer(const char *name);

答案 2 :(得分:6)

int *const func() const

除少数情况外,您无法在此处观察const

  • func
  • 的地址
  • 在C ++ 0x中,使用函数调用语法直接调用func作为decltype操作数,将产生int * const

这是因为你返回一个纯指针值,也就是说指针值实际上没有存储在指针变量中。这些值不是const限定的,因为它们无论如何都不能改变。即使您带走了obj.func() = NULL;,也无法说const。在这两种情况下,表达式obj.func()都有 类型int*并且是不可修改的(有人会很快引用标准并提出“rvalue”一词)。

因此,在上下文中,您使用返回值,您将无法找到差异。如果您参考声明或整个功能本身,您会注意到差异。

const int* func() const

如果身体像return &this->intmember;那样,你通常会这样做。它不允许通过执行*obj.func() = 42;来更改int成员。

const int * const func() const

这只是前两个的组合:)

答案 3 :(得分:1)

返回指向const的指针很有意义,但是返回一个const指针(你无法修改)通常不会添加任何值(尽管有人说它可以防止用户错误或添加编译器优化)。

这是因为返回值属于函数的调用者,即它是他们自己的副本,所以如果他们修改它(指向别的东西)并不重要。但是内容并不“属于”调用者,并且函数的实现者可以签订它是只读信息的契约。

Const成员函数承诺不会更改类的状态,尽管编译器实际上并不一定强制执行。我这里不是指const_cast或mutable成员,而是如果你的类本身包含指针或引用,const成员函数将你的指针转换为常量指针,但不会使它们指向const,同样你的引用不会被转换到const-references。如果这些是您的类的组件(并且此类组件通常由指针表示),则您的函数可以更改其状态。

可变成员的目的是让你的班级在不改变内部状态的同时改变他们。这些通常可以应用于:

  • 您希望锁定的互斥锁,即使是阅读。
  • 延迟加载的数据,即第一次访问时填充的数据。
  • 引用计数对象:如果它有另一个查看器,您希望增加引用计数,因此您只需修改其状态即可读取它。

const_cast通常被认为是“hack”,并且通常在其他人没有正确地编写其代码时完成。它可以在以下情况下具有价值:

  • 多个重载,其中一个是const,一个是非const,const返回一个const-reference,non-const返回一个非const引用,但是它们是相同的。复制代码(如果它不是一个简单的数据成员获取)不是一个好主意,所以用另一个实现一个并使用const_cast来绕过编译器。

  • 您希望特别调用const重载但具有非const引用。首先将它投射到const。

答案 4 :(得分:0)

const方法阻止您修改成员。如果是指针,这意味着您无法重新指定指针。您可以修改指针所指向的对象,以满足您的心愿。

当指针由值(副本)返回时,调用者不能使用它来修改类的指针成员。因此,将const添加到返回值不会增加任何内容。

如果要返回对指针的引用,情况会有所不同。现在,如果指针不是const,这意味着没有权限修改值的函数会将此权限授予调用者。

示例:

class X
{
    int* p;
public:
    int* get_copy_of_pointer() const //the returned value is a copy of this->p
    { 
        *p = 42;  //this being const doesn't mean that you can't modify the pointee
        //p = 0;  //it means you can't modify the pointer's value
        return p; 
    }
    int* const& get_reference_to_pointer() const //can't return a reference to non-const pointer
    {
        return p;
    }
};
相关问题