А почему не использовать уже определённое умножение?
Можно, но моя формула требует 

 умножений и 

 сдвиг (умножение на 

), а обычное умножение требует 

 умножений, что, примерно, в 2 раза медленнее.
Разве плохо рассматривать числа без цифр как ноль?
Не подумал, спасибо!
Случай равной длины можно, во-первых, слить с любым из оставшихся двух. Плюс, насколько мне мерещится, у вас для каждого случая код дублируется, хотя можно было бы создать один приватный метод сложения чисел, когда первое, скажем, не короче второго, и использовать в этих двух случаях, так как сложение случайно оказалось коммутативным. 
 Всё верно, спасибо! Про коммутативность забыл 
 Мне очень нравится реализация длинки, которая приведена на emaxx
Ну, там по-детски 
 Вместо того, чтобы обнулять результат, скопируйте в него большее число и прибавьте к нему меньшее.
Спасибо!
Можете объявить вспомогательную функцию или оператор +=.
Я сделал наоборот: += через + 

Код:
BigInt& BigInt::operator+=(const BigInt& rhs)
{
   *this = *this + rhs;
   return *this;
}
За счет того, что мне нужно выделять размер на 

 больше, а функции realloc у нас, будем считать, нет, выигрыша мы не получим (если я опять ничего не пропустил).
По-моему, uint64 - это лучший вариант.
Я имел ввиду, что не везде он есть.
Пишите короткие функции. Не бойтесь делать много функций. Используйте, заимствуйте уже написанный протестированный и отработанный код. 
А также я бы вам по рекомендовал подумать над тем, как можно уменьшить ваш код.
Стараюсь 
 К примеру указатели обменять.
Можно по-подробнее, пожалуйста?
Сравнил. По-моему, там не очень интересная реализация 

К сожалению, на квадрат у меня пока времени не было, зато плюс доделал. Мало того, что код уменьшился, так ещё и работает немного быстрее (скорее всего из-за рекомендации Xaositect'а).
(Оффтоп)
Код:
BigInt BigInt::operator+(const BigInt& rhs) const
{
   if (m_length >= rhs.m_length)
   {
      if (m_length == 0)
         return rhs;
      if (rhs.m_length == 0)
         return *this;
      BigInt result(m_integer, m_length + 1); // !!!
      result.m_integer[m_length] = 0;
      for (uint32 i = 0; i < rhs.m_length; ++i)
         result.m_integer[i] += rhs.m_integer[i];
      for (uint32 i = 0; i < rhs.m_length; ++i)
         if (result.m_integer[i] < m_integer[i])
            while (++result.m_integer[i + 1] == 0)
               ++i;      
      return result;
   }
   else
      return rhs + *this;
}
Но есть одна проблема в помеченном месте: я считываю память за пределами выделенной -- это нормально или так делать нельзя?