BlockLune's Blog

Home Tags About |

static_cast and const_cast in C++

This is a note for Lecture 8, CS106L, Spring 2023.

In a class like this:

class StrVector {
 public:
  using iterator = std::string*;
  const size_t kInitialSize = 2;
  /*...*/
  size_t size() const;
  bool empty() const;
  void push_back(const std::string& elem);
  std::string& at(size_t indx);
  const std::string& at(size_t indx) const;

  iterator begin();
  iterator end();
  iterator cbegin() const;
  iterator cend() const;
  /*...*/
};

We implement the non-const at method like this:

std::string& StrVector::at(size_t index) {
  if (index >= size()) {
    throw std::out_of_range("Index out of range in at.");
  }
  return *(begin() + index);
}

It is bad to reimplement the same logic when writing the const version of the at method.

// bad
const std::string& StrVector::at(size_t index) const {
  if (index >= size()) {
    throw std::out_of_range("Index out of range in at.");
  }
  return *(cbegin() + index);
}

Instead, we should do this:

const std::string& StrVector::at(size_t index) const {
  return static_cast<const std::string&>(
      const_cast<StrVector*>(this)->at(index));
}

So, what’s static_cast and const_cast?

static_cast<new-type>(expression) is used to convert from one type to another. For example: int my_int = static_cast<int>(3.1). Note that it CANNOT BE USED WHEN conversion would cast away constness.

Learn more here

const_cast<new-type>(expression) is used to cast away (remove) constness. It allows you to make non-const pointer or reference to const-object like this:

const int const_int = 3;
int& my_int = const_cast<int&>(const_int);

Learn more here