CS106L Winter2025 Assignment5 Treebook

关于CS106L的第五个作业的个人解法

写在前面

本文取自Stanford CS106L Winter2025 Assignment5: Treebook 本作业主要需要我们在其他人完成了一个类的情况下,将此类变得更加适用、更加好用,主要包括运算符重载、special member function等方面,总的来说不算难(比上次的好多了)

具体思路

Viewing Profiles

目前,我们拥有一个User类,其中值得注意的是_friends这个field,它简单来说是一个vector,但更底层,是使用指针来实现的。 此题需要我们重载<<这个操作符,使得其打印时更符合我们人类的直觉 关于如何重载此操作符,如果没有思路,可以先看看这篇文章为自己的类重载 << 运算符 User(name=Alice, friends=[Bob, Charlie]),可以看出,除了简单的必须存在的字符串以外,我们还需要打印自己的name,friends的name, 自己的name很简单,类中已经给出方法get_name() friends的name,就需要思考了,首先friends在private里,这意味着我们不能简单访问它们,而是使用friend function,其次还应明白如何访问一个指针元素,最后还要注意当我们到最后一个friend时,要改变打印的内容,因此可以写出代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
std::ostream& operator<<(std::ostream& os, const User& us) {
  os << "User(name=" << us.get_name() << ", friends=[";

  for (size_t i = 0; i < us.size(); ++i) {
    if (i == us.size() - 1) {
      os << us._friends[i];
    } else {
      os << us._friends[i] << ", ";
    }
  }
  os << "])";
  return os;
}

Unfriendly Behaviour

此题需要我们实现Special Member Functions,具体为

  • Destructor 一般来说析构函数是不需要自己显式声明的,但若遇见了与内存相关的内容,就需要我们显式声明了,在此处,_friends就使用了内存,在全部完成后,需要释放内存
1
  ~User();
1
2
3
User::~User() {
  delete[] _friends;
}
  • Copy Constructor 复制一个已存在的对象,将其声明为新的对象,值得注意的是,需要手动分配内存以保证_friends的正确性,在此处,笔者使用的是教授教的C++11的新方法,
1
  User(const User& user);
1
2
3
4
5
6
7
8
9
User::User(const User& user):
  _name(user._name),
  _size(user._size),
  _capacity(user._capacity),
  _friends(new std::string[user._capacity]) {
    for (size_t i = 0; i < user._size; ++i) {
      _friends[i] = user._friends[i];
    }
  }
  • Copy Assignment 以上课时的内容为基准,举一反三既可
1
  User& operator=(const User& user);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
User& User::operator=(const User& user) {
  if (this == &user) {
    return *this;
  }
  delete[] _friends;

  _name = user._name;
  _size = user._size;
  _capacity = user._capacity;
  _friends = new std::string[user._capacity];
  for (size_t i = 0; i < user._size; i++) {
    _friends[i] = user._friends[i];
  }
  return *this;
}
  • Move Constructor & Move Assignment 此处要用到的内容为移动语义的知识,为了防止被移动,我们要显示删除这两个SMF,简单声明即可
1
2
  User(User&& user) = delete;
  User& operator=(User&& user) = delete;

Always Be Friending

此处需要我们重载两个操作符,以使得其更符合此类的操作

  • operator+= 将一个用户添加到另一个用户上以成为其朋友,值得注意的是,这是相互的,一个人对另一个人敞开心扉后,另一个人也应如此。 最后还应按照题目要求返回*this
1
  User& operator+=(User& rhs);
1
2
3
4
5
User& User::operator+=(User& rhs) {
  this->add_friend(rhs.get_name());
  rhs.add_friend(this->get_name());
  return *this;
}
  • operator< 简单判断第一个字符的先后即可
1
  bool operator<(const User& rhs) const;
1
2
3
bool User::operator<(const User& rhs) const {
  return this->get_name()[0] < rhs.get_name()[0];
}

GitHub地址

不会摄影的药师不是好程序员
使用 Hugo 构建
主题 StackJimmy 设计