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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3888470/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:59:05  来源:igfitidea点击:

c++ const member function that returns a const pointer.. But what type of const is the returned pointer?

c++const

提问by Jor

I apologize if this has been asked, but how do I create a member function in c++ that returns a pointer in the following scenerios: 1. The returned pointer is constant, but the junk inside can be modified. 2. The junk inside is constant but the returned pointer can be modified. 3. Neither the junk, nor the pointer can be modified.

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

Is it like so:

是不是这样:

  1. int *const func() const
  2. const int* func() const
  3. const int * const func() const
  1. int *const func() const
  2. const int* func() const
  3. const int * const func() const

All of the tutorials I've read don't cover this distinction.

我读过的所有教程都没有涵盖这种区别。

Side note: If my method is declared const then the tutorials say that I'm stating that I won't modify the parameters.. But this is not clear enough for me in the case when a parameter is a pointer. Do my parameters need to be like:

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

a. void func(const int* const x) const;
b. void func(const int* x) const;
c. void func(const int* const x) const;

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

回答by Armen Tsirunyan

I don't know what book you have read, but if you mark a method const it means that thiswill be of type const MyClass*instead of MyClass*, which in its turn means that you cannot change nonstatic data members that are not declared mutable, nor can you call any non-const methods on this.

我不知道你读过什么书,但是如果你将一个方法标记为 const 则意味着this它将是类型const MyClass*而不是MyClass*,这反过来意味着你不能更改未声明的非静态数据成员mutable,也不能调用任何上的非常量方法this

Now for the return value.

现在是返回值。

1 . int * const func () const

1 . int * const func () const

The function is constant, and the returned pointer is constant but the 'junk inside' can be modified. However, I see no point in returning a const pointer because the ultimate function call will be an rvalue, and rvalues of non-class type cannot be const, meaning that constwill be ignored anyway

该函数是常量,返回的指针是常量,但可以修改“内部垃圾”。但是,我认为返回 const 指针没有意义,因为最终的函数调用将是一个右值,而非类类型的右值不能是const,这意味着const无论如何都会被忽略

2 . const int* func () const

2 . const int* func () const

This is a useful thing. The "junk inside" cannot be modified

这是一个有用的东西。“里面的垃圾”无法修改

3 . const int * const func() const

3 . const int * const func() const

semantically almost the same as 2, due to reasons in 1.

由于 1 中的原因,语义上几乎与 2 相同。

HTH

HTH

回答by Patrick

Some uses of const don't really make much sense.

const 的某些用途并没有多大意义。

Suppose you have the following function:

假设您有以下功能:

void myFunction (const int value);

The const tells the compiler that value must not change inside the function. This information does not have any value for the caller. It's up to the function itself to decide what to do with the value. For the caller, the following two function definitions behave exactly the same for him:

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

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

Because value is passed by value, which means that the function gets a local copy anyway.

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

On the other hand, if the argument is a reference or a pointer, things become very different.

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

void myFunction (const MyClass &value);

This tells the caller that value is passed by reference (so behind the screens it's actually a pointer), but the caller promises not to change value. The same is true for pointers:

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

void myFunction (const MyClass *value);

We pass a pointer to MyClass (because of performance reasons), but the function promises not to change the value.

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

If we would write the following:

如果我们写如下:

void myFunction (MyClass * const value);

Then we are back int he first situation. myFunction gets a pointer, which is passed by value, and which is const. Since MyFunction gets a copy of the pointer value, it doesn't matter for the caller whether it is const or not. The most important thing is that myFunction can change the contents of value, because the pointer variable itself is const, but the contents in it isn't.

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

The same is true for return values:

返回值也是如此:

const double squareRoot(double d);

This doesn't make any sense. squareRoot returns a const double but since this is passed 'by value', and thus needs to be copied to my own local variable, I can do whatever I want with it.

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

On the other hand:

另一方面:

const Customer *getCustomer(char *name);

Tells me that getCustomer returns me a pointer to a customer, and I am not allowed to change the contents of the customer.

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

Actually, it would be better to make the char-pointer-contents const as well, since I don't expect the function to change the given string:

实际上,最好也使 char-pointer-contents 为 const ,因为我不希望该函数更改给定的字符串:

const Customer *getCustomer(const char *name);

回答by Johannes Schaub - litb

int *const func() const

int *const func() const

You cannot observe the consthere except for a few cases

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

  • Taking the address of func.
  • In C++0x, directly calling funcwith the function-call syntax as a decltypeoperand, will yield int * const.
  • 取地址func.
  • 在 C++0x 中,直接func使用函数调用语法作为decltype操作数调用,将产生int * const.

This is because you return a pure pointer value, that is to say a pointer value not actually stored in a pointer variable. Such values are not const qualified because they cannot be changed anyway. You cannot say obj.func() = NULL;even if you take away the const. In both cases, the expression obj.func()has the type int*and is non-modifiable (someone will soon quote the Standard and come up with the term "rvalue").

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

So in contexts you use the return value you won't be able to figure a difference. Just in cases you refer to the declaration or whole function itself you will notice the difference.

因此,在使用返回值的上下文中,您将无法计算出差异。只是在您引用声明或整个函数本身的情况下,您会注意到差异。

const int* func() const

const int* func() const

This is what you usually would do if the body would be something like return &this->intmember;. It does not allow changing the int member by doing *obj.func() = 42;.

如果身体像return &this->intmember;. 它不允许通过执行*obj.func() = 42;.

const int * const func() const

const int * const func() const

This is just the combination of the first two :)

这只是前两者的结合:)

回答by CashCow

Returning a pointer to const makes a lot of sense, but returning a const pointer (you cannot modify) usually adds no value (although some say it can prevent user errors or add compiler optimisation).

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

That is because the return value belongs to the caller of the function, i.e. it is their own copy so it doesn't really matter if they modify it (to point to something else). The content however does not "belong" to the caller and the implementor of the function may make a contract that it is read-only information.

那是因为返回值属于函数的调用者,即它是他们自己的副本,所以他们是否修改它(指向其他东西)并不重要。然而,内容不“属于”调用者,函数的实现者可以约定它是只读信息。

Const member functions promise not to change the state of the class, although this is not necessarily enforced in reality by the compiler. I am not referring here to const_cast or mutable members so much as the fact that if your class itself contains pointers or references, a const member function turns your pointers into constant pointers but does not make them pointers to const, similarly your references are not turned into references-to-const. If these are components of your class (and such components are often represented by pointers) your functions can change their state.

Const 成员函数承诺不会改变类的状态,尽管这在现实中不一定由编译器强制执行。我在这里指的不是 const_cast 或可变成员,而是如果您的类本身包含指针或引用,那么 const 成员函数会将您的指针转换为常量指针,但不会使它们指向 const,类似地,您的引用不会被转换成对 const 的引用。如果这些是您的类的组件(并且此类组件通常由指针表示),则您的函数可以更改它们的状态。

Mutable members are there for the benefit of allowing your class to change them whilst not changing internal state. These can typically be applied to:

可变成员的存在是为了让您的类在不改变内部状态的情况下更改它们。这些通常可以应用于:

  • Mutexes that you wish to lock even for reading.
  • Data that is lazy-loaded, i.e. filled in the first time they are accessed.
  • Reference-counted objects: You want to increase the reference count if it has another viewer, thus you modify its state just to read it.
  • 即使为了读取,您也希望锁定的互斥锁。
  • 延迟加载的数据,即在第一次访问时填充的数据。
  • 引用计数对象:如果它有另一个查看器,您希望增加引用计数,因此您修改其状态只是为了读取它。

const_cast is generally considered a "hack" and is often done when someone else has not written their code properly const-correct. It can have value though in the following situations:

const_cast 通常被认为是一种“hack”,通常在其他人没有正确地编写他们的代码时使用 const-correct 。但在以下情况下它可能有价值:

  • Multiple overloads where one is const and one non-const and the const returns a const-reference and the non-const returns a non-const reference, but otherwise they are the same. Duplicating the code (if it is not a simple data member get) is not a great idea, so implement one in terms of the other and use const_cast to get around the compiler.

  • Where you want in particular to call the const overload but have a non-const reference. Cast it to const first.

  • 多个重载,其中一个是常量,一个是非常量,并且常量返回一个常量引用,非常量返回一个非常量引用,但除此之外它们是相同的。复制代码(如果它不是一个简单的数据成员 get)不是一个好主意,因此根据另一个实现一个并使用 const_cast 绕过编译器。

  • 你特别想调用 const 重载但有一个非常量引用的地方。首先将其转换为 const。

回答by visitor

The const method prevents you from modifying the members. In case of pointers, this means you can't reassign the pointer. You can modify the object pointed at by the pointer to your heart's desire.

const 方法可防止您修改成员。在指针的情况下,这意味着您不能重新分配指针。您可以修改指针指向的对象,指向您的心愿。

As the pointer is returned by value (a copy), the caller can't use it to modify the pointer member of the class. Hence adding const to the return value adds nothing.

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

Things are different if you were to return a reference to the pointer. Now, if the pointer weren't const, this would mean that a function that doesn't have rights to modify a value is granting this right to the caller.

如果您要返回对指针的引用,情况就不一样了。现在,如果指针不是常量,这意味着无权修改值的函数正在向调用者授予此权限。

Example:

例子:

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;
    }
};