Как создать объект класса с
Конструкторы представляют специальную функцию, которая имеет то же имя, что и класс, которая не возвращает никакого значения и которая позволяют инициалилизировать объект класса во время го создания и таким образом гарантировать, что поля класса будут иметь определенные значения. При каждом создании нового объекта класса вызывается конструктор класса.
В прошлой теме был разработан следующий класс:
#include class Person < public: std::string name; unsigned age; void print() < std::cout >; int main() < Person person; // вызов конструктора person.name = "Tom"; person.age = 22; person.print(); >
Здесь при создании объекта класса Person, который называется person
Person person;
вызывается конструктор по умолчанию . Если мы не определяем в классе явным образом конструктор, как в случае выше, то компилятор автоматически компилирует конструктор по умолчанию. Подобный конструктор не принимает никаких параметров и по сути ничего не делает.
Теперь определим свой конструктор. Например, в примере выше мы устанавливаем значения для полей класса Person. Но, допустим, мы хотим, чтобы при создании объекта эти поля уже имели некоторые значения по умолчанию. Для этой цели определим конструктор:
#include class Person < public: std::string name; unsigned age; void print() < std::cout Person(std::string p_name, unsigned p_age) < name = p_name; age = p_age; std::cout >; int main() < Person tom("Tom", 38); // создаем объект - вызываем конструктор tom.print(); >
Теперь в классе Person определен конструктор:
Person(std::string p_name, unsigned p_age)
По сути конструктор представляет функцию, которая может принимать параметры и которая должна называться по имени класса. В данном случае конструктор принимает два параметра и передает их значения полям name и age, а затем выводит сообщение о создании объекта.
Если мы определяем свой конструктор, то компилятор больше не создает конструктор по умолчанию. И при создании объекта нам надо обязательно вызвать определенный нами конструктор.
Вызов конструктора получает значения для параметров и возвращает объект класса:
Person tom("Tom", 38);
После этого вызова у объекта person для поля name будет определено значение «Tom», а для поля age — значение 38. Вполедствии мы также сможем обращаться к этим полям и переустанавливать их значения.
В качестве альтернативы для создания объекта можно использовать инициализатор в фигурных скобках:
Person tom;
Тажке можно присвоить объекту результат вызова конструктора:
Person tom = Person("Tom", 38);
По сути она будет эквивалетна предыдущей.
Консольный вывод определенной выше программы:
Person has been created Name: Tom Age: 38
Конструкторы облегчают нам создание нескольких объектов, которые должны иметь разные значения:
#include class Person < public: std::string name; unsigned age; void print() < std::cout Person(std::string p_name, unsigned p_age) < name = p_name; age = p_age; std::cout >; int main() < Person tom; Person bob; Person sam; tom.print(); bob.print(); sam.print(); >
Здесь создаем три разных объекта класса Person (условно трех разных людей), и соответственно в данном случае консольный вывод будет следующим:
Person has been created Person has been created Person has been created Name: Tom Age: 38 Name: Bob Age: 42 Name: Sam Age: 25
Определение нескольких конструкторов
Подобным образом мы можем определить несколько конструкторов и затем их использовать:
#include class Person < std::string name<>; unsigned age<>; public: void print() < std::cout Person(std::string p_name, unsigned p_age) < name = p_name; age = p_age; >Person(std::string p_name) < name = p_name; age = 18; >Person() < name = "Undefined"; age = 18; >>; int main() < Person tom; // вызываем конструктор Person(std::string p_name, unsigned p_age) Person bob; // вызываем конструктор Person(std::string p_name) Person sam; // вызываем конструктор Person() tom.print(); bob.print(); sam.print(); >
В классе Person определено три конструктора, и в функции все эти конструкторы используются для создания объектов:
Name: Tom Age: 38 Name: Bob Age: 18 Name: Undefined Age: 18
Хотя пример выше прекрасно работает, однако мы можем заметить, что все три конструктора выполняют фактически одни и те же действия — устанавливают значения переменных name и age. И в C++ можем сократить их определения, вызова из одного конструктора другой и тем самым уменьшить объем кода:
#include class Person < std::string name<>; unsigned age<>; public: void print() < std::cout Person(std::string p_name, unsigned p_age) < name = p_name; age = p_age; std::cout Person(std::string p_name): Person(p_name, 18) // вызов первого конструктора < std::cout Person(): Person(std::string("Undefined")) // вызов второго конструктора < std::cout >; int main() < Person sam; // вызываем конструктор Person() sam.print(); >
Запись Person(string p_name): Person(p_name, 18) представляет вызов конструктора, которому передается значение параметра p_name и число 18. То есть второй конструктор делегирует действия по инициализации переменных первому конструктору. При этом второй конструктор может дополнительно определять какие-то свои действия.
Таким образом, следующее создание объекта
Person sam;
будет использовать третий конструктор, который в свою очередь вызывает второй конструктор, а тот обращается к первому конструктору.
Данная техника еще называется делегированием конструктора , поскольку мы делегируем инициализацию другому конструктору.
Параметры по умолчанию
Как и другие функции, конструкторы могут иметь параметры по умолчанию:
#include class Person < std::string name; unsigned age; public: // передаем значения по умолчанию Person(std::string p_name = "Undefined", unsigned p_age = 18) < name = p_name; age = p_age; >void print() < std::cout >; int main() < Person tom; Person bob; Person sam; tom.print(); // Name: Tom Age: 38 bob.print(); // Name: Bob Age: 18 sam.print(); // Name: Undefined Age: 18 >
Инициализация констант и списки инициализации
В теле конструктора мы можем передать значения переменным класса. Однако константы требуют особого отношения. Например, вначале определим следующий класс:
class Person < const std::string name; unsigned age<>; public: void print() < std::cout Person(std::string p_name, unsigned p_age) < name = p_name; age = p_age; >>;
Этот класс не будет компилироваться из-за отсутствия инициализации константы name. Хотя ее значение устанавливается в конструкторе, но к моменту, когда инструкции из тела конструктора начнут выполняться, константы уже должны быть инициализированы. И для этого необходимо использовать списки инициализации :
#include class Person < const std::string name; unsigned age<>; public: void print() < std::cout Person(std::string p_name, unsigned p_age) : name < age = p_age; >>; int main() < Person tom; tom.print(); // Name: Tom Age: 38 >
Списки инициализации представляют перечисления инициализаторов для каждой из переменных и констант через двоеточие после списка параметров конструктора:
Person(std::string p_name, unsigned p_age) : name
Здесь выражение name позволяет инициализировать константу значением параметра p_name. Здесь значение помещается в фигурные скобки, но также можно использовать кргулые:
Person(std::string p_name, unsigned p_age) : name(p_name)
Списки инициализации пободным образом можно использовать и для присвоения значений переменным:
class Person < const std::string name; unsigned age; public: void print() < std::cout Person(std::string p_name, unsigned p_age) : name(p_name), age(p_age) < >>;
При использовании списков инициализации важно учитывать, что передача значений должна идти в том порядке, в котором константы и переменные определены в классе. То есть в данном случае в классе сначала определена константа name, а потом переменная age. Соответственно в таком же порядке идет передача им значений. Поэтому при добавлении дополнительных полей или изменения порядка существующих придется следить, чтобы все инициализировалось в належащем порядке.
- Глава 1. Введение в С++
- Язык программирования С++
- Первая программа на Windows. Компилятор g++
- Первая программа на Windows. Компилятор Clang
- Первая программа на Windows. Компилятор Microsoft Visual C++
- Первая программа на Linux. Компилятор g++
- Первая программа на MacOS. Компилятор Clang
- Настройка параметров компиляции
- Локализация и кириллица в консоли
- Структура программы
- Переменные
- Типы данных
- Константы
- Ввод и вывод в консоли
- using. Подключение пространств имен и определение псевдонимов
- Арифметические операции
- Статическая типизация и преобразования типов
- Поразрядные операции
- Операции присваивания
- Условные выражения
- Конструкция if-else и тернарный оператор
- Конструкция switch-case
- Циклы
- Ссылки
- Массивы
- Многомерные массивы
- Массивы символов
- Введение в строки
- Что такое указатели
- Операции с указателями
- Арифметика указателей
- Константы и указатели
- Указатели и массивы
- Определение и объявление функций
- Область видимости объектов
- Параметры функции
- Передача аргументов по значению и по ссылке
- Константные параметры
- Оператор return и возвращение результата
- Указатели в параметрах функции
- Массивы в параметрах функции
- Параметры функции main
- Возвращение указателей и ссылок
- Перегрузка функций
- Рекурсивные функции
- Рекурсия на примере быстрой сортировки
- Указатели на функции
- Указатели на функции как параметры
- Тип функции
- Указатель на функцию как возвращаемое значение
- Разделение программы на файлы
- Внешние объекты
- Динамические объекты
- Динамические массивы
- unique_ptr
- shared_ptr
- Определение классов
- Конструкторы и инициализация объектов
- Управление доступом. Инкапсуляция
- Объявление и определение функций класса
- Конструктор копирования
- Константные объекты и функции
- Ключевое слово this
- Дружественные функции и классы
- Статические члены класса
- Деструктор
- Структуры
- Перечисления
- Наследование
- Управление доступом в базовых и производных классах
- Скрытие функционала базового класса
- Множественное наследование
- Виртуальные функции и их переопределение
- Преобразование типов
- Динамическое преобразование
- Особенности динамического связывания
- Чистые виртуальные функции и абстрактные классы
- Перегрузка операторов
- Операторы преобразования типов
- Оператор индексирования
- Переопределение оператора присваивания
- Пространства имен
- Вложенные классы
- Обработка исключений
- Вложенные try-catch
- Создание своих типов исключений
- Тип exception
- Типы исключений
- Шаблоны функций
- Шаблон класса
- Специализация шаблона класса
- Наследование и шаблоны классов
- Типы контейнеров
- Вектор
- Итераторы
- Операции с векторами
- Array
- List
- Forward_list
- Deque
- Стек std::stack
- Очередь std::queue
- Очередь приоритетов std::priority_queue
- Множества
- Словарь std::map
- Span
- Определение строк
- Строки с поддержкой Unicode
- Преобразование типов и строки
- Сравнение строк
- Получение подстроки и проверка начала и конца строки
- Поиск подстроки
- Изменение строки
- Операции с символами
- Программа подсчета слов
- Тип std:string_view
- rvalue
- Конструктор перемещения
- Оператор присваивания с перемещением
- Роль noexcept при перемещении
- Объекты функций
- Лямбда-выражения
- Захват внешних значений в лямбда-выражениях
- Шаблон std::function<>
- Минимальный и максимальный элементы
- Поиск элементов
- Копирование элементов
- Удаление элементов и идиома Remove-Erase Idiom
- Сортировка
- Представления. Фильтрация
- Проекция данных
- Пропуск элементов. drop_view и drop_while_view
- Извлечение диапазона элементов. take_view и take_while_view
- Цепочки представлений
- Оператор requires
- Концепты
- Выражение requires
- Ограничения типа для auto
- Базовые типы для работы с потоками
- Файловые потоки. Открытие и закрытие
- Чтение и запись текстовых файлов
- Переопределение операторов ввода и вывода
- Математические константы и операции
- Форматирование строк и функция format
- std::optional
- Управление ресурсами. Идиома RAII
- Идиома копирования и замены
- Идиома Move-and-Swap
- Первая программа в Visual Studio
- Первая программа в Qt Creator
Классы, структуры и пространства имен
C# является полноценным объектно-ориентированным языком. Это значит, что программу на C# можно представить в виде взаимосвязанных взаимодействующих между собой объектов.
Описанием объекта является класс , а объект представляет экземпляр этого класса. Можно еще провести следующую аналогию. У нас у всех есть некоторое представление о человеке, у которого есть имя, возраст, какие-то другие характеристики. То есть некоторый шаблон — этот шаблон можно назвать классом. Конкретное воплощение этого шаблона может отличаться, например, одни люди имеют одно имя, другие — другое имя. И реально существующий человек (фактически экземпляр данного класса) будет представлять объект этого класса.
В принципе ранее уже использовались классы. Например, тип string , который представляет строку, фактически является классом. Или, например, класс Console , у которого метод WriteLine() выводит на консоль некоторую информацию. Теперь же посмотрим, как мы можем определять свои собственные классы.
По сути класс представляет новый тип, который определяется пользователем. Класс определяется с помощью ключевого слова сlass :
class название_класса < // содержимое класса >
После слова class идет имя класса и далее в фигурных скобках идет собственно содержимое класса. Например, определим в файле Program.cs класс Person, который будет представлять человека:
class Person
Начиная с версии C# 12, если класс имеет пустое определение, то фигурные скобки после названия типа можно не использовать:
class Person;
Однако такой класс не особо показателен, поэтому добавим в него некоторую функциональность.
Поля и методы класса
Класс может хранить некоторые данные. Для хранения данных в классе применяются поля . По сути поля класса — это переменные, определенные на уровне класса.
Кроме того, класс может определять некоторое поведение или выполняемые действия. Для определения поведения в классе применяются методы.
Итак, добавим в класс Person поля и методы:
class Person < public string name = "Undefined"; // имя public int age; // возраст public void Print() < Console.WriteLine($"Имя: Возраст: "); > >
В данном случае в классе Person определено поле name , которое хранит имя, и поле age , которое хранит возраст человека. В отличие от переменных, определенных в методах, поля класса могут иметь модификаторы, которые указываются перед полем. Так, в данном случае, чтобы все поля были доступны вне класса Person поля определены с модификатором public .
При определении полей мы можем присвоить им некоторые значения, как в примере выше в случае переменной name . Если поля класса не инициализированы, то они получают значения по умолчанию. Для переменных числовых типов это число 0.
Также в классе Person определен метод Print() . Методы класса имеют доступ к его поля, и в данном случае обращаемся к полям класса name и age для вывода их значения на консоль. И чтобы этот метод был виден вне класса, он также определен с модификатором public .
Создание объекта класса
После определения класса мы можем создавать его объекты. Для создания объекта применяются конструкторы . По сути конструкторы представляют специальные методы, которые называются так же как и класс, и которые вызываются при создании нового объекта класса и выполняют инициализацию объекта. Общий синтаксис вызова конструктора:
new конструктор_класса(параметры_конструктора);
Сначала идет оператор new , который выделяет память для объекта, а после него идет вызов конструктора .
Конструктор по умолчанию
Если в классе не определено ни одного конструктора (как в случае с нашим классом Person), то для этого класса автоматически создается пустой конструктор по умолчанию, который не принимает никаких параметров.
Теперь создадим объект класса Person:
Person tom = new Person(); // создание объекта класса Person // определение класса Person class Person < public string name = "Undefined"; public int age; public void Print() < Console.WriteLine($"Имя: Возраст: "); > >
Для создания объекта Person используется выражение new Person() . В итоге после выполнения данного выражения в памяти будет выделен участок, где будут храниться все данные объекта Person. А переменная tom получит ссылку на созданный объект, и через эту переменную мы можем использовать данный объект и обращаться к его функциональности.
Обращение к функциональности класса
Для обращения к функциональности класса — полям, методам (а также другим элементам класса) применяется точечная нотация точки — после объекта класса ставится точка, а затем элемент класса:
объект.поле_класса объект.метод_класса(параметры_метода)
Например, обратимся к полям и методам объекта Person:
Person tom = new Person(); // создание объекта класса Person // Получаем значение полей в переменные string personName = tom.name; int personAge = tom.age; Console.WriteLine($"Имя: Возраст "); // Имя: Undefined Возраст: 0 // устанавливаем новые значения полей tom.name = "Tom"; tom.age = 37; // обращаемся к методу Print tom.Print(); // Имя: Tom Возраст: 37 class Person < public string name = "Undefined"; public int age; public void Print() < Console.WriteLine($"Имя: Возраст: "); > >
Консольный вывод данной программы:
Имя: Undefined Возраст: 0 Имя: Tom Возраст: 37
Добавление класса
Обычно классы помещаются в отдельные файлы. Нередко для одного класса предназначен один файл. Если мы работаем над проектом вне среды Visual Studio, используя .NET CLI, то нам достаточно добавить новый файл класса в папку проекта. Например, добавим новый файл, который назовем Person.cs и в котором определим следующий код:
class Person < public string name = "Undefined"; public void Print() < Console.WriteLine($"Person "); > >
Здесь определен класс Person с одним полем name и методом Print.
В файле Program.cs , который представляет основной файл программы используем класс Person:
Person tom = new Person(); tom.name = "Tom"; tom.Print(); // Person Tom
Visual Studio предоставляет по умолчанию встроенные шаблоны для добвления класса. Для добавления класса нажмем в Visual Studio правой кнопкой мыши на название проекта:
В появившемся контекстном меню выберем пункт Add -> New Item. (или Add -> Class. )
В открывшемся окне добавления нового элемента убедимся, что в центральной части с шаблонами элементов у нас выбран пункт Class . А внизу окна в поле Name введем название добавляемого класса — пусть он будет назваться Person :
В качестве названия класса можно вводить как Person, так и Person.cs. И после нажатия на кнопку добавления в проект будет добавлен новый класс, в котором можно определить тот же код и также использовать в файле Program.cs.
Таким образом, мы можем определять классы в отдельных файлах и использовать их в программе.
Классы, структуры и пространства имен
C# является полноценным объектно-ориентированным языком. Это значит, что программу на C# можно представить в виде взаимосвязанных взаимодействующих между собой объектов.
Описанием объекта является класс , а объект представляет экземпляр этого класса. Можно еще провести следующую аналогию. У нас у всех есть некоторое представление о человеке, у которого есть имя, возраст, какие-то другие характеристики. То есть некоторый шаблон — этот шаблон можно назвать классом. Конкретное воплощение этого шаблона может отличаться, например, одни люди имеют одно имя, другие — другое имя. И реально существующий человек (фактически экземпляр данного класса) будет представлять объект этого класса.
В принципе ранее уже использовались классы. Например, тип string , который представляет строку, фактически является классом. Или, например, класс Console , у которого метод WriteLine() выводит на консоль некоторую информацию. Теперь же посмотрим, как мы можем определять свои собственные классы.
По сути класс представляет новый тип, который определяется пользователем. Класс определяется с помощью ключевого слова сlass :
class название_класса < // содержимое класса >
После слова class идет имя класса и далее в фигурных скобках идет собственно содержимое класса. Например, определим в файле Program.cs класс Person, который будет представлять человека:
class Person
Начиная с версии C# 12, если класс имеет пустое определение, то фигурные скобки после названия типа можно не использовать:
class Person;
Однако такой класс не особо показателен, поэтому добавим в него некоторую функциональность.
Поля и методы класса
Класс может хранить некоторые данные. Для хранения данных в классе применяются поля . По сути поля класса — это переменные, определенные на уровне класса.
Кроме того, класс может определять некоторое поведение или выполняемые действия. Для определения поведения в классе применяются методы.
Итак, добавим в класс Person поля и методы:
class Person < public string name = "Undefined"; // имя public int age; // возраст public void Print() < Console.WriteLine($"Имя: Возраст: "); > >
В данном случае в классе Person определено поле name , которое хранит имя, и поле age , которое хранит возраст человека. В отличие от переменных, определенных в методах, поля класса могут иметь модификаторы, которые указываются перед полем. Так, в данном случае, чтобы все поля были доступны вне класса Person поля определены с модификатором public .
При определении полей мы можем присвоить им некоторые значения, как в примере выше в случае переменной name . Если поля класса не инициализированы, то они получают значения по умолчанию. Для переменных числовых типов это число 0.
Также в классе Person определен метод Print() . Методы класса имеют доступ к его поля, и в данном случае обращаемся к полям класса name и age для вывода их значения на консоль. И чтобы этот метод был виден вне класса, он также определен с модификатором public .
Создание объекта класса
После определения класса мы можем создавать его объекты. Для создания объекта применяются конструкторы . По сути конструкторы представляют специальные методы, которые называются так же как и класс, и которые вызываются при создании нового объекта класса и выполняют инициализацию объекта. Общий синтаксис вызова конструктора:
new конструктор_класса(параметры_конструктора);
Сначала идет оператор new , который выделяет память для объекта, а после него идет вызов конструктора .
Конструктор по умолчанию
Если в классе не определено ни одного конструктора (как в случае с нашим классом Person), то для этого класса автоматически создается пустой конструктор по умолчанию, который не принимает никаких параметров.
Теперь создадим объект класса Person:
Person tom = new Person(); // создание объекта класса Person // определение класса Person class Person < public string name = "Undefined"; public int age; public void Print() < Console.WriteLine($"Имя: Возраст: "); > >
Для создания объекта Person используется выражение new Person() . В итоге после выполнения данного выражения в памяти будет выделен участок, где будут храниться все данные объекта Person. А переменная tom получит ссылку на созданный объект, и через эту переменную мы можем использовать данный объект и обращаться к его функциональности.
Обращение к функциональности класса
Для обращения к функциональности класса — полям, методам (а также другим элементам класса) применяется точечная нотация точки — после объекта класса ставится точка, а затем элемент класса:
объект.поле_класса объект.метод_класса(параметры_метода)
Например, обратимся к полям и методам объекта Person:
Person tom = new Person(); // создание объекта класса Person // Получаем значение полей в переменные string personName = tom.name; int personAge = tom.age; Console.WriteLine($"Имя: Возраст "); // Имя: Undefined Возраст: 0 // устанавливаем новые значения полей tom.name = "Tom"; tom.age = 37; // обращаемся к методу Print tom.Print(); // Имя: Tom Возраст: 37 class Person < public string name = "Undefined"; public int age; public void Print() < Console.WriteLine($"Имя: Возраст: "); > >
Консольный вывод данной программы:
Имя: Undefined Возраст: 0 Имя: Tom Возраст: 37
Добавление класса
Обычно классы помещаются в отдельные файлы. Нередко для одного класса предназначен один файл. Если мы работаем над проектом вне среды Visual Studio, используя .NET CLI, то нам достаточно добавить новый файл класса в папку проекта. Например, добавим новый файл, который назовем Person.cs и в котором определим следующий код:
class Person < public string name = "Undefined"; public void Print() < Console.WriteLine($"Person "); > >
Здесь определен класс Person с одним полем name и методом Print.
В файле Program.cs , который представляет основной файл программы используем класс Person:
Person tom = new Person(); tom.name = "Tom"; tom.Print(); // Person Tom
Visual Studio предоставляет по умолчанию встроенные шаблоны для добвления класса. Для добавления класса нажмем в Visual Studio правой кнопкой мыши на название проекта:
В появившемся контекстном меню выберем пункт Add -> New Item. (или Add -> Class. )
В открывшемся окне добавления нового элемента убедимся, что в центральной части с шаблонами элементов у нас выбран пункт Class . А внизу окна в поле Name введем название добавляемого класса — пусть он будет назваться Person :
В качестве названия класса можно вводить как Person, так и Person.cs. И после нажатия на кнопку добавления в проект будет добавлен новый класс, в котором можно определить тот же код и также использовать в файле Program.cs.
Таким образом, мы можем определять классы в отдельных файлах и использовать их в программе.
Создание объекта класса
@dizar47, Если вам дан исчерпывающий ответ, отметьте его как верный (нажмите на галку рядом с выбранным ответом). Это касается всех ваших вопросов!
2 мая 2012 в 14:42
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
Это делается через один большой if/case (в зависимости от кол-ва и ситуации). То есть, в общем виде это будет выглядеть как
class Text : public TBaseClass <>; class Word : public TBaseClass <>; TBaseClass n; if (obj_name == "Text") < n = new Text(); >else if (obj_name == "Word") < n = new Word(); >else
Когда классов будет больше 3-5, все это дело заворачивают в map, ключ — имя, значение — функция/метод, которая может создать класс.
Отслеживать
ответ дан 2 мая 2012 в 14:16
112k 6 6 золотых знаков 94 94 серебряных знака 161 161 бронзовый знак
Я так понял, что автор имеет ввиду создание экземпляра объекта с произвольным именем — любым.
2 мая 2012 в 14:24С произвольным именем не получиться. У класса может не быть конструктора по умолчанию. Но главное препятствие в том, что в с++ классы не имеют общего предка. Поэтому, класс то создать можно, но что с ним потом делать.
2 мая 2012 в 14:32
В любом случае это бессмыслица. Все эти имена (классов, переменных, пр.) исчезают на этапе компиляции. Варианты с внешними штуками типа CORBA, COM и т.д. — разговор отдельный. А на стадии выполнения имён уже нет (могут быть в RTTI, но их значение не обязано быть читабельным)
2 мая 2012 в 14:43
Могут исчезать, но компилятор не обязан так делать. Он может и сохранить.
2 мая 2012 в 14:49
И даже обязан. Если требуется информация для отладчика.
2 мая 2012 в 15:20В C++ такое невозможно.
Отслеживать
ответ дан 2 мая 2012 в 14:08
vladimir_ki vladimir_ki
1,923 10 10 серебряных знаков 12 12 бронзовых знаковТы можешь попробовать сделать это например используя контейнер Map:
#include #include #include using namespace std; class CustomClass < public: //. void test()< cout >; int main() < mapclasses; string className; cin >> className; CustomClass *one = new CustomClass(); classes.insert(make_pair(className, one)); classes[className]->test(); // или classes["ручками пишем"]->test(); return 0; >
Но у данного метода есть проблемы, если много классов вставить в контейнер то понадобится время для их поиска, хотя это может быть не критично.
Если вам нужно обращаться так к классам разного типа, то придется создавать отдельно контейнеры, например:
map iMap; map myMap; map tClass;
и позже производить поиск нужного элемента в каждом из них.
Чтобы не создавать кучу контейнеров под каждый класс, можно создать базовый класс для всех ваших классов которые вы хотите так использовать, а в контейнере хранить указатель на базовый класс, например:
#include #include #include using namespace std; class MyBase < //.. >; class Player : public MyBase < //.. >; class Home : public MyBase < //.. >; int main() < mapclasses; string className; cin >> className; Player *player = new Player(); classes.insert(make_pair(className, player)); cin >> className; Home *home = new Home(); classes.insert(make_pair(className, home)); Player* myPlayer = dynamic_cast(classes[className]); return 0; >
Ну а чтобы позже получить нужный вам класс из базового можно использовать dynamic_cast. Но вам необходимо будет точно знать какой класс скрывается за данным именем, чтобы преобразовать указатель на базовый класс в нужный нам класс.
И вот подкину еще костыльный вариант, это в базовом классе создать enum с типами всех ваших классов и переменную хранящую этот enum, приведу готовый говнокод:
#include #include #include using namespace std; class MyBase < public: MyBase()< classType = ClassType::MyBase; >enum class ClassType < MyBase = 0, Player, Home // и т.д. если у вас есть еще наследники данного класса MyBase >ClassType getType() const < return classType; >protected: ClassType classType; >; class Player : public MyBase < public: Player()< classType = ClassType::Player; >//.. >; class Home : public MyBase < public: Home()< classType = ClassType::Home; >//.. >; int main() < mapclasses; string className; cin >> className; Player *player = new Player(); classes.insert(make_pair(className, player)); cin >> className; Home *home = new Home(); classes.insert(make_pair(className, home)); MyBase* ptr = classes[className]; Player* playerPtr = nullptr; auto type = ptr->getType(); if (type == MyBase::ClassType::Home)< playerPtr = dynamic_cast(ptr); // Получили указатель на объект нужного типа > return 0; >