如何提供const版本的运算符 - >对于句柄类

时间:2017-08-28 06:21:34

标签: c++

我正在尝试重载我的运算符 - > for句柄类返回const和非const指针,指向基类。

查看我发布的代码,在试用函数中,如果我添加了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)) ===|

我的问题是,是否可以这样做,如果是的话,我可以知道什么是正确的实施方案?

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

}

2 个答案:

答案 0 :(得分:1)

只需返回指向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();
}

如果您担心const和非const重载中的重复代码,请参阅Const function calling non const or vice versa (to avoid duplication)?

答案 1 :(得分:0)

如果你重载operator->,行为将不会模仿内置指针(并且完全没有意义)。

内置指针有两种形式:指针和指向const的指针。 (我们在这里忽略volatile)。这些风格是不同的类型。指针本身是const与它们指向的constness无关。

为了模仿这种行为,你需要两种版本的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) { ... }
  };

标准智能指针是类模板,因此可以只写shared_ptr<Cards>shared_ptr<const Cards>