Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hw02 && 模板 && 迭代器 #53

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

Sduby22
Copy link

@Sduby22 Sduby22 commented Feb 8, 2022

作业要求

  • 避免函数参数不必要的拷贝 5 分
    • print()函数以及push_front()函数中可以将参数类型改为常量引用,避免拷贝
  • 修复智能指针造成的问题 10 分
    • 对于双向链表,相邻项之间存在循环引用,引用计数无法归零释放空间。
    • 可以使用unique_ptr + Node*的方式解决
  • 改用 unique_ptr<Node> 10 分
    • 对于双向链表,可以看作前一项“拥有”后一项。 而后一项保留前一项的Node*指针
    • List拥有一个headunique_ptr
  • 实现拷贝构造函数为深拷贝 15 分
    • 遍历等号右端List,逐项调用定义的push_back(value_type const &)函数即可
  • 说明为什么可以删除拷贝赋值函数 5 分
    • 此处拷贝赋值 = 拷贝构造出右值+移动赋值
  • 改进 Node 的构造函数 5 分
    • 构造value,而不是默认构造后再赋值。
    • 即把构造的部分放在冒号和花括号中间

改为模板

  • Node, List均定义为模板
  • 修改value为模板类型
  • 修改List中成员函数的某些参数或返回值类型为对应的模板类型

迭代器

参考: Prepare the custom iterator

第一次自定义迭代器,使用了std::bidirectional_iterator_tag,没有定义const_iterator。

    class iterator {
    public:
        using iterator_category = std::bidirectional_iterator_tag;
        using difference_type   = std::ptrdiff_t;
        using value_type        = Node<T>;
        using pointer           = value_type*;  // or also value_type*
        using reference         = value_type&;  // or also value_type&

        iterator(pointer ptr): m_ptr(ptr) {}
        reference operator*() { return *m_ptr; }
        pointer operator->() { return m_ptr; }

        // Prefix increment
        iterator& operator++() 
        { m_ptr = m_ptr->next.get(); return *this; }  

        // Postfix increment
        iterator operator++(int) 
        { iterator tmp = *this; ++(*this); return tmp; }

        friend bool operator== (const iterator& a, const iterator& b) 
        { return a.m_ptr == b.m_ptr; };
        friend bool operator!= (const iterator& a, const iterator& b) 
        { return a.m_ptr != b.m_ptr; };     

    private:
        Node<T>* m_ptr;
    };

@Sduby22 Sduby22 changed the title Hw02 Hw02 && 模板 && 迭代器 Feb 8, 2022
Copy link
Contributor

@archibate archibate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 避免函数参数不必要的拷贝 4/5 分
  • 修复智能指针造成的问题 10/10 分
  • 改用 unique_ptr<Node> 7/10 分
  • 实现拷贝构造函数为深拷贝 13/15 分
  • 说明为什么可以删除拷贝赋值函数 4/5 分
  • 改进 Node 的构造函数 5/5 分
  • 能够在 PR 描述中用自己的话解释 25/25 分
  • 代码格式规范、能够跨平台 5/5 分
  • 有自己独特的创新点 18/20 分

91分!

改进建议:实现 const_iterator 和 cbegin/cend。

};

void print(List lst) { // 有什么值得改进的?
void print(List<int> &lst) { // 有什么值得改进的?: 传入const引用,避免拷贝
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void print(List<int> &lst) { // 有什么值得改进的?: 传入const引用,避免拷贝
void print(List<int> const &lst) { // 有什么值得改进的?: 传入const引用,避免拷贝


List() = default;

List(List const &other) {
List(List &other) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
List(List &other) {
List(List const &other_) {
List &other = const_cast<List &>(other_);

拷贝构造函数有特定的函数签名,不建议轻易改变。

auto curr = front();
for (size_t i = 0; i < index; i++) {
curr = curr->next.get();
}
return curr;
}

iterator begin() { return iterator(head.get()); }
iterator end() { return iterator(nullptr); }
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以在这里声明两个 const 版本的 begin 和 end。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants