简体   繁体   English

如何提供操作符的const版本->用于句柄类

[英]How to provide const version of operator -> for a handle class

I am trying to overload my operator-> for a handle class to return const and non const pointer, pointing towards a base class. 我试图重载我的operator->以使句柄类返回const和非const指针,指向基类。

Looking at the code i posted, in the trial function, if i add in the const keyword, the error message will be 查看我发布的代码,在试用功能中,如果我添加const关键字,则错误消息将为

||=== Build: Debug in Const trial (compiler: GNU GCC Compiler) ===|
C:\Const trial\main.cpp
||In function 'bool trial(Cards_pointer)':|
C:\Const trial\main.cpp|50|error: passing 'const Cards_pointer' as 'this' argument of 'Cards*& Cards_pointer::operator->()' discards qualifiers [-fpermissive]|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

My question is whether it is possible to do so, if yes, may i know what is the correct implementation? 我的问题是是否可以这样做,如果可以,请问我知道正确的实施方法是什么?

#include <iostream>
#include<vector>
#include<stdexcept>
#include<algorithm>
using namespace std;

class Cards
{
private:
    int x;
public:
    Cards():x(3) {}
    int rx()const
    {
        return x;
    }
};

class Cards_pointer
{
private:
    Cards* cp;
    size_t* refptr;

public:
//default constructor
    Cards_pointer():cp(0),refptr(new size_t(1)) {}
    Cards_pointer(Cards*t):cp(t),refptr(new size_t(1)) {}
//copy constructor
    Cards_pointer (const Cards_pointer&s):cp(s.cp),refptr(s.refptr)
    {
        refptr=s.refptr;
        cp=s.cp;
//++*refptr;
        *refptr=*refptr+1;
    }

    Cards*&operator->()
    {
        if(cp)
            return cp;

        else throw std::runtime_error("uninitialized Cards");
    }

};

bool trial(const Cards_pointer x)
{
    if(x->rx()==3)
        return true;

    return false;
}

int main()
{
    Cards_pointer x=new Cards();

    bool cond=trial(x);

}

Just return a pointer to const and provide a const qualified overload 只需返回指向const的指针并提供const限定的重载

class Something {
public:
    void bar() {}
    void foo() const {}
};

class Wrapper {
public:
    Something* operator->() {
        return &this->something;
    }
    const Something* operator->() const {
        return &this->something;
    }
private:
    Something something;
};

int main() {
    const auto c_wrapper = Wrapper{};
    c_wrapper->foo();
    // The below is an error
    // c_wrapper->bar();
    auto m_wrapper = Wrapper{};
    m_wrapper->bar();
}

If you are worried about duplicated code in the const and non const overloads see Const function calling non const or vice versa (to avoid duplication)? 如果您担心const和non const重载中的代码重复,请参阅Const函数调用non const或反之(以避免重复)?

If you overload your operator-> , the behaviour will not mimick that of built-in pointers (and will not make much sense at all). 如果您重载operator-> ,则该行为将不会模仿内置指针的行为(并且完全没有意义)。

Built-in pointers come in two flavours: pointers and pointers-to-const. 内置指针有两种形式:指针和指向常量的指针。 (We ignore volatile here). (我们在这里忽略了volatile)。 These flavours are different types. 这些口味是不同的类型。 Pointers themselves being const have nothing to do with constness of what they point to. 指针本身就是常量,与指针指向的常量无关。

In order to imitate this behaviour, you need two flavours of Cards_pointer, one with operator-> that returns a normal pointer, and one with operator-> that returns a pointer-to-const. 为了模仿这种行为,您需要两种Cards_pointer,一种是带有operator->指针,该指针返回普通指针,另一种带有operator->的指针,该指针返回指向const的指针。

  class Cards_pointer_base { ... };
  class Cards_pointer: private Cards_pointer_base {         
     public:
       // usual constructors/assignment operators
       using ...; // necessary members from the base
       Cards* operator->() { ... }
  };
  class Cards_const_pointer: private Cards_pointer_base {         
     public:
       // usual constructors/assignment operators
       using ...; // necessary members from the base
       const Cards* operator->() { ... }
       // conversions from pointer to non-const
       Cards_const_pointer(const Cards_pointer& from) { ... }
       Cards_const_pointer& operator=(const Cards_pointer& from) { ... }
  };

Standard smart pointers are class templates, so one can just write shared_ptr<Cards> and shared_ptr<const Cards> . 标准的智能指针是类模板,因此可以只编写shared_ptr<Cards>shared_ptr<const Cards>

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

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