#CS100S25HW601. Basic Knowledge

Basic Knowledge

Problem 1. Basic knowledge

  1. Consider the following code about static members. Which statements are true?
class Counter {
  static int count;
public:
  static void increment() { ++count; }
  static int get() { return count; }
};
int Counter::count = 0;

{{ multiselect(1) }}

  • count is shared among all instances of Counter.
  • The initialization of Counter::count must be done outside the class definition.
  • increment() can access non-static member variables of Counter.
  • Counter::get() can be called without any Counter object instance.
  • Static member functions have no this pointer.
  1. Read the following code about move semantics. Which statements are true?
class Data {
  int* ptr;
public:
  Data(Data&& other) noexcept : ptr(other.ptr) { other.ptr = nullptr; }
  Data& operator=(Data&& other) noexcept {
    delete ptr;
    ptr = other.ptr;
    other.ptr = nullptr;
    return *this;
  }
};

{{ multiselect(2) }}

  • The moved-from object will be immediately destructed after calling move assignment/constructor.
  • The move assignment operator should check for self-assignment.
  • Move operations typically don't throw exceptions and are marked noexcept.
  • If we define a move constructor, the compiler will automatically generate a copy constructor.
  • The expression other.ptr = nullptr in move constructor prevents double deletion.
  1. Which statements about smart pointers are correct?

{{ multiselect(3) }}

  • std::unique_ptr allows multiple pointers to manage the same object.
  • std::make_shared is preferred over new for creating std::shared_ptr.
  • std::shared_ptr uses reference counting to manage resources.
  • std::unique_ptr can be returned from a function by moving.
  • std::shared_ptr has no overhead compared to raw pointers.
  1. Consider the following code about operator overloading. Which statements are true?
class Vector {
  int x, y;
public:
  Vector operator+(const Vector& rhs) const {
    return Vector(x + rhs.x, y + rhs.y);
  }
  friend std::ostream& operator<<(std::ostream& os, const Vector& v);
};

{{ multiselect(4) }}

  • The + operator is overloaded as a member function.
  • operator+ can access private members of rhs.
  • operator<< must be declared as a friend to access private members.
  • The expression v1 + v2 is equivalent to v1.operator+(v2).
  • operator+ returns a reference to a temporary object.
  1. Which statements about type conversions are correct?

{{ multiselect(5) }}

  • explicit constructors prevent implicit conversions.
  • Type conversion can only occur through (implicit/explicit) conversion opeator function call.
  • operator bool() should usually be explicit.
  • A constructor with multiple parameters can be a conversion function.
  • Contextual conversion to bool works even with explicit operators.
  1. Read the following code about destructors. Which statements are true?
class ResourceHolder {
  int* ptr;
public:
  ~ResourceHolder() { delete ptr; }
  ResourceHolder(ResourceHolder&& other) : ptr(other.ptr) { other.ptr = nullptr; }
};

{{ multiselect(6) }}

  • The destructor ensures no memory leak occurs.
  • The move constructor leaves the source object in a destructible state.
  • If we define a destructor, the compiler will delete move operations.
  • The class follows the Rule of Five.
  • ptr should be checked for nullptr before deletion in destructor.
  1. Which statements about rvalue references are correct?

{{ multiselect(7) }}

  • std::move converts an lvalue to an rvalue reference.
  • An rvalue reference parameter can bind to lvalues.
  • int&& x = 5; is valid.
  • After moving an object, its state is unspecified.
  • Rvalue references extend the lifetime of temporary objects.
  1. Consider the following code about friend functions. Which statements are true?
class Box {
  int width;
  friend void printWidth(const Box&);
};
void printWidth(const Box& b) { std::cout << b.width; }

{{ multiselect(8) }}

  • printWidth can access private members of Box.
  • printWidth is a member function of Box.
  • Friend declarations can appear in any section (public/private) of the class.
  • printWidth must be defined inside the class.
  • Friendship is inherited in derived classes.
  1. Which statements about std::unique_ptr are correct?

{{ multiselect(9) }}

  • It can be copied if the managed object is const.
  • It automatically releases memory when going out of scope.
  • std::unique_ptr<T[]> uses delete[] for deallocation.
  • Moving a unique_ptr transfers ownership.
  1. Consider the following code about type aliases. Which statements are true?
class Container {
public:
  using size_type = std::size_t;
  using value_type = int;
};

{{ multiselect(10) }}

  • size_type can be accessed as Container::size_type.
  • Type alias members are independent of access specifiers(private, protected, public).
  • value_type can be modified by class users.
  • Type aliases can be used within member functions.
  • using declarations can replace typedef completely in C++.