Converting numbers to English words
Short review: The purpose of code is to tell other programmers what you're telling the computer to do. Your code here reads like you're trying show off all these cool things you can do - which makes for very difficult to read, unimplementable code. Don't perform multiple operations and checks on one line. Don't use member variables to do temporary state. Structure your code to make your intent as readily apparent to the reader as possible. 

readInput

Seriously, just no:

while((std::cout &lt;&lt; prompt) &amp;&amp; (!(std::cin &gt;&gt; answer) || answer &lt; 0 || answer &gt; 99999999))


There is never any reason to write code like that. Why even pass a prompt to the function if you're going to write a different string anyway? I don't see a reason for the prompt. 

main

You should write a function that looks like:

std::string convertNumber(int );


Having a streamable class is gratuitous.

NumberConverter

The flow of this class doesn't make much logical sense. You have a member variable mNumber, that you're modifying as you go. It's really more like an implicit argument to convert(). Same with all the member variables actually. Makes it very difficult to reason about the correctness of convert().

words[] doesn't make sense as an array. The three elements in the array have nothing to do with each other. You have the numbers under 20, you have the tens numbers (why the hyphen?) and the block identifiers. Declaring it this way means you have a bunch of cryptic words[2][0] or words[1][index] expressions. Prefer to make three different vectors and name them appropriately. 

So convert() takes both a units and its string representation? That's not good design since you're basically passing the same/similar information twice. Prefer to restructure this call such that you're converting one "block" at a time (e.g. the millions block, then the thousands block, then the unit block). Redundant information is bad. 

This fragment doesn't make sense either:

std::string word = words[1][index];

if (word[word.size() - 1] == '-')


Why are you using the specific word format as a signal for something? Also, all the words in words[1] end in a hyphen so you always go into this block.