首页 > 解决方案 > 返回非常量引用会导致绑定引用错误

问题描述

我已经使用弱指针和智能指针实现了一个双链表。const该程序正在运行,但我在getPrev签名方法中对此表示怀疑。如果我 const在方法签名的末尾加上一个,它将导致绑定引用错误

error: binding reference of type 'std::weak_ptr<Node<Integer> >&' to 'const std::weak_ptr<Node<Integer> >' discards qualifiers
         return prev;

这样做的目的不是const标记*thisconst吗?根据我的理解,返回类型是非常量的。

这是代码,main.cpp

#include <memory>
#include <iostream>
#include "DoubleLinkedList.h"

class Integer {
private:
    int number;
public:
    Integer(int number) : number(number) {}

    int get() { return number; }

};

int main() {

    DoubleLinkedList<Integer> list;
    list.insert(Integer(1));
    list.insert(Integer(2));
    list.insert(Integer(3));
    list.insert(Integer(4));
    list.insert(Integer(5));


    return 0;
}

DoubleLinkedList.h

#include <memory>
#include <vector>
#include <iostream>

template <typename T>
class Node {
private:
    T data;
    std::weak_ptr<Node> prev;
    std::shared_ptr<Node> next;
public:
    Node(): data(0) {}

    Node(const T &object) : data(object) {};

    T getData() const {
        return data;
    }

    void setData(T data) {
        Node::data = data;
    }

    std::weak_ptr<Node> &getPrev() const {
        return prev;
    }

    void setPrev(const std::weak_ptr<Node> &prev) {
        Node::prev = prev;
    }

    std::shared_ptr<Node> &getNext() {
        return next;
    }

    void setNext(const std::shared_ptr<Node> &next) {
        Node::next = next;
    }
};

template <typename T>
class DoubleLinkedList {
private:
    std::shared_ptr<Node<T>> header;
    std::weak_ptr<Node<T>> trailer;
    int size;
public:

    DoubleLinkedList() : size(0) {}

    void insert(const T &value) {
        auto node = std::make_shared<Node<T>>(value);

        if (size++ == 0) {
            header = node;
        } else {
            auto last = trailer.lock();
            last->getNext() = node;
            node->getPrev() = last;
        }
        trailer = node;
    }


};

标签: c++

解决方案


如果你在一个const方法内部,所有的数据成员都会被考虑const

也就是说,在这个函数内部:

std::weak_ptr<Node> &getPrev() const

你可以想象这样的成员变量:

const T data;
const std::weak_ptr<Node> prev;
const std::shared_ptr<Node> next;

应该清楚的是,您不能返回对 const 对象的非常量引用:

const int x;

int& getX()
{
  return x; // error
}

引用将允许您修改x,即使它是const,所以这是被禁止的(正式地:非常量引用不能绑定到 const 对象)。

在 , 的const成员函数Node内部prev是 a const std::weak_ptr<Node>,因此std::weak_ptr<Node>&出于完全相同的原因 a 不能绑定到它。


看来insert您确实打算修改node(通过更改其prev值),在这种情况下,getPrev函数不应该是 const (因为您打算修改对象)。但是这种访问权限可能应该保留给外部用户,DoubleLinkedList而不是一些任意的外部用户。然后它变成了界面设计的问题:您的代码的哪些部分是实现细节以及应该如何对用户隐藏这些部分?哪些部分是用户应该与之交互的界面(破坏事物的机会最小)?


推荐阅读