Имеется такой класс:
public class Env
{
private Hashtable table;
protected Env prev;
public Env(Env n)
{
table = new HashTable();
prev = n;
}
}
Вопрос в том, как передавать через конструктор объект этого же типа в с++?
Нужно понимать, что в с++ лучше использовать не обьекты напрямую а указатели либо ссылки. (объект - непрерывный участок в памяти, если в коде объект без указателя - он встраивается в scope-область видимости другого обьекта, для "самостоятельности" [т.е. что б не был встроен] нужно использовать указатель либо ссылку) Просто нужно добавить в местах обьявления обьектов - указатель(звёздочка). Кстати - new - возращает указатель. Для упрощения - в java тоже передаётся указатель, но синтаксиз упростили.
class Env
{
private: Hashtable * table;
protected: Env * prev;
public: Env(Env * n)
{
table = new HashTable();
prev = n;
}
}
Запись Hashtable table; валидна, но обьект в таком случае будет создан и уничтожен неявно (new не требуется), и обьект имеет "стационарное место", т.е. его нельзя прямо так "копировать". В зависимости от конкретной ситуации так можно или нельзя делать (нужно понимать зона видимости и выход за неё, для table без new можно, для prev нельзя т.к. присвоение идет). Можно отдельно почитать про обьекты в с++. В большинстве случаев проще использовать * при передаче обьектов.
Я иногда путаю названия ссылка & и указатель *. Указатель может быть null. Тут речь идет об указателе, который ссылается на обьект. Вместо точки при указателе прийдётся писать -> (например table->toString()). Работать с ссылочным типом или с обьектом без указателя в с++ - несколько сложнее (зато там привычная точка).
UPD ещё немного. В с++ по умолчанию нету уборщика мусора в отличии от java - колличество new должно позже равнятся колличеству delete (что б небыло утечки памяти), но так же существует уборщик в виде отдельных библиотек.
При переводе кода с одного языка на другой возникает множество нюансов, особенно когда языки не имеют между собой какого-то родственного отношения.
В Java используются ссылочные типы данных, т.е. для записи вида public Env(Env n) фактически происходит передача ссылки (читай как адреса) объекта n в конструктор класса Env. Т.е. непосредственно до начала кода самого конструктора никакого копирования пользовательских данных ещё нет.
При этом стоит иметь в виду ещё такую особенность, что в Java используется сборщик мусора (Garbage Collector), и (по большей части) нет необходимости следить за временем жизни объектов, если ссылка на объект доступна, то и сам объект живой.
Суть вашего конструктора - формирование некоего линейного однонаправленного списка. Каждый новый объект Env создаёт таблицу и запоминает переданный аргумент, как некий предыдущий объект. Здесь стоит учесть тот вариант, что вызов Env(null) по сути начинает новый список, теряя все предыдущие объекты, если их не запомнить где-то дополнительно.
Учитывая необходимость передачи null в конструктор, подходящим вариантом использования в с++ будет указатель. Но так как в С++ нет сборщика мусора, а следить за валидностью объектов по сырым указателям не очень благодарная работа в современном мире, наиболее эквивалентным способом здесь будет использование умного указателя, т.е. обёртки вида std::shared_ptr (объект жив, пока доступен указатель и объект не копируется при копировании указателей, почти как в Java!) над вашим Env. А для table как приватного члена разумнее вовсе отказаться от указателя и хранить его по значению. Таким образом, результирующий код на C++, максимально близкий по поведению коду Java мне видится таким:
#include <memory>
class Hashtable { /* */ };
class Env
{
public:
Env(std::shared_ptr<Env> n)
{
prev = n;
}
protected:
std::shared_ptr<Env> prev;
private:
Hashtable table;
};
Можно заметить, что в С++ отпала необходимость создавать явно объект table, т.к. он хранится в классе по значению, и в конструкторе Env создаётся конструктором по умолчанию (по сути то же, что в Java делается вызовом new HashTable();)
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости