简体   繁体   English

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

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

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. 如果有人询问,我道歉,但是如何在c ++中创建一个成员函数,在以下scenerios中返回一个指针:1。返回的指针是常量,但可以修改里面的垃圾。 2. The junk inside is constant but the returned pointer can be modified. 2.里面的垃圾是常量但可以修改返回的指针。 3. Neither the junk, nor the pointer can be modified. 3.垃圾和指针都不能被修改。

Is it like so: 是这样的:

  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. 旁注:如果我的方法被声明为const,那么教程说我说我不会修改参数..但是在参数是指针的情况下,这对我来说还不够清楚。 Do my parameters need to be like: 我的参数需要像:

a. 一个。 void func(const int* const x) const;
b. void func(const int* x) const;
c. C。 void func(const int* const x) const;

I don't know what book you have read, but if you mark a method const it means that this will 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 . 我不知道是什么书你读过,但如果你标记的方法常量就意味着this将是类型的const MyClass* ,而不是MyClass* ,这反过来意味着你不能改变未声明的非静态数据成员mutable ,也不能在this调用任何非const方法。

Now for the return value. 现在为返回值。

1 . 1。 int * const func () const

The function is constant, and the returned pointer is constant but the 'junk inside' can be modified. 函数是常量,返回的指针是常量,但可以修改'junk inside'。 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 const will be ignored anyway 但是,我认为返回一个const指针是没有意义的,因为最终的函数调用将是一个rvalue,而非类类型的rvalues不能是const ,这意味着const无论如何都会被忽略

2 . 2。 const int* func () const

This is a useful thing. 这是一件有用的事情。 The "junk inside" cannot be modified “垃圾内部”无法修改

3 . 3。 const int * const func() const

semantically almost the same as 2, due to reasons in 1. 由于1中的原因,语义几乎与2相同。

HTH HTH

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. const告诉编译器,函数内部的值不能改变。 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: 对于调用者,以下两个函数定义对他来说完全相同:

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. myFunction获取一个指针,该指针由值传递,并且是const。 Since MyFunction gets a copy of the pointer value, it doesn't matter for the caller whether it is const or not. 由于MyFunction获取指针值的副本,因此调用者是否为const并不重要。 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,但其中的内容不是。

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,但由于它是'by value'传递的,因此需要复制到我自己的局部变量,我可以用它做任何我想做的事情。

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

int *const func() const

You cannot observe the const here except for a few cases 除少数情况外,你不能在这里观察const

  • Taking the address of func . func的地址。
  • In C++0x, directly calling func with the function-call syntax as a decltype operand, will yield int * const . 在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. 这些值不是const限定的,因为它们无论如何都不能改变。 You cannot say obj.func() = NULL; 你不能说obj.func() = NULL; even if you take away the const . 即使你带走了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"). 在这两种情况下,表达式obj.func()的类型都是int*并且是不可修改的(有人会很快引用标准并提出术语“rvalue”)。

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

This is what you usually would do if the body would be something like return &this->intmember; 这就是你通常会做的事情,如果身体会像return &this->intmember; . It does not allow changing the int member by doing *obj.func() = 42; 它不允许通过执行*obj.func() = 42;更改int成员*obj.func() = 42; .

const int * const func() const

This is just the combination of the first two :) 这只是前两个的组合:)

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, ie 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. Const成员函数承诺不会改变类的状态,尽管编译器实际上并不一定强制执行。 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. 我不是在这里指const_cast或mutable成员,而是如果你的类本身包含指针或引用,const成员函数将你的指针转换为常量指针,但不会使它们指向const,类似你的引用不会被转换到const-references。 If these are components of your class (and such components are often represented by pointers) your functions can change their state. 如果这些是您的类的组件(并且此类组件通常由指针表示),则您的函数可以更改其状态。

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, ie 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. const_cast通常被认为是“hack”,并且通常在其他人没有正确编写正确的代码时完成。 It can have value though in the following situations: 在以下情况下它可以有价值:

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

  • Where you want in particular to call the const overload but have a non-const reference. 您特别想要调用const重载但具有非const引用的位置。 Cast it to const first. 首先将其转换为const。

The const method prevents you from modifying the members. const方法阻止您修改成员。 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. 您可以修改指针所指向的对象,以满足您的心愿。

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. 现在,如果指针不是const,这将意味着没有权限修改值的函数将此权限授予调用者。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM