Зі стрічкою - це зветься "серіалізація/десеріалізація". Найпростіше: просто записуєте всі елементи свого класу до стрічки; треба лише продумати:
- розділювачі: наприклад, можна розділяти окремі значення символом '\n' (новий рядок), тоді доведеться якось кодувати його в стрічках, наприклад, замінювати на "\\n" (комбінація \ та n). Ну і сам символ \ доведеться записувати як \\ (так само як і у звичайному коді на C). Або просто написати, що новий рядок не кодується і замінювати, якщо зустрінеться, на пробіл.
- як зберігати складні елементи (елементи інших класів) - їх часто краще зберігати не повністю, а посиланням, скажімо, тим самим номером з INumbering. А іноді навпаки. По ситуації.
Читати потім все у тому ж порядку.
Якщо маєте бажання - можете в JSON пхати/читати. Або перед елементом зберігати його довжину.
Метод, що створює об'єкт зі стрічки, швидше за все буде статичним і повертати сам об'єкт (фабрикою). Або взагалі не елементом інтерфейсу (як це, "об'єкт, прочитай себе зі стрічки" - це до кого звертання?)
З нумерацією - вам потрібен спільний контейнер для елементів класу. Наприклад, статичний член класу - вектор. Або словник (map<адреса елемента, номер>), що передається в конструктор параметром. Або геш-таблиця (unordered_map), збережена в сінглетоні. Коротше, обмежень немає, головне, щоб воно було спільне для всіх елементів класу. Найпростіше прямо в конструкторі брати номер, а в деструкторі звільняти.
Якщо нумерація не має зберігатися в серіалізованому вигляді і не мають бути якось впорядковані (я не бачу в завданні нічого про персистентність), то найпростіше використовувати як номери адреси об'єктів, тоді лише кількість треба зберігати десь.
До речі, а в завданні точно треба створювати об'єкт від цих інтерфейсів? Тобто це, звісно, чудова ідея - перевірити, чи воно працює, але ви не написали, що так треба зробити.
Іще пара зауважень до стилю.
1. Дотримуйтеся єдиного стилю найменувань. Загальна порада - типи UpperCamelCase, змінні та функції snake_case, елементи класів snake_case_underscore_. Але, звісно, можна функції lowerCamelCase, а елементи класів m_snake_case чи m_lowerCamelCase, головне - щоб стиль був єдиний. Тобто number() і StrToObj() не мають бути одночасно методами класу, це плутає в першу чергу вас.
2. Називайте ідентифікатори повністю, не лінуйтеся. Ви витратите значно більше часу на зневадженні коду, в якому переплутали n та k, ніж на вигадування і набирання слів object_number_ та total_objects_ (звісно, можете викинути object, щоб було щось на кшталт m_number та m_total).
2. Функції та методи краще називати з дієсловом, або хоча б так, щоб було добре зрозуміло, що це якась дія. get_number, get_quality, to_string, from_string. Якщо дія складніша за просте повернення поля - використовуйте не get, а find, calculate і т.д. І немає сенсу згадувати об'єкт - якщо це метод, то він застосовується з іменем об'єкту (порівняйте MyCar.ObjToStr() та MyCar.ToString()).
3. Приватні члени класу, хоча й можуть проголошуватися без ключового слова, краще переносити в кінець коду класу. Тих, хто читатиме код, цікавитимуть у першу чергу публічні методи.
І наступного разу, будь ласка, не викладайте код одразу (якщо він є). Це нам дуже допомагає відповідати.