In the old (very old) days, compilers worked like this:
- The compiler generated assembly code in a file and wrote it to disk,
- The assembler took that file and generated the binary.
These days, unless you really want assembly output, your compiler does not generate explicit assembly language code. It will just generate some assembly in memory but then convert it to machine code themselves and only write the machine code to file. This is what your instructor meant when saying that C/C++ gets directly converted to machine code.
There is one more important thing you should know. Machine code is basically the same thing as assembly language. In assembly languages, instructions have names and written using strings, but these are the same instructions (one-to-one mapping) that are used in machine code. This is important so I repeat myself: machine code and and assembly are the same, only written in different notations.
This is why any binary can be disassembled; because to convert something from machine code to assembly, you just have to change the representation (translate each instruction and its operands from binary to "mnemonic" form.
So, modern compilers may actually not generate the actual strings that represents instructions (e.g. mov rax, 42
) for performance reasons. If nobody wants the assembly output, why waste the memory and processing power generating it? But of course they do generate the equivalent machine code, which is faster for a compiler to generate.