@Mishele123

Почему не работает метод clone для класса Test1?

Учу в вузе ооп. Решил немного попрактиковаться. Написал код:
#include <iostream>
#include <vector>
#include <memory>


class Test
{
protected:
	std::string _name;

public:
	Test(std::string name) : _name(name) {}
	std::string get_name()
	{
		return _name;
	}
	void Print()
	{
		std::cout << _name << std::endl;
	}
	virtual std::shared_ptr<Test> clone() const = 0;
protected:
	Test() = default;
	Test(Test&) = default;
	Test& operator=(const Test&) = default;
};

class Test1 : public Test
{
	int _age;

public:
	Test1() : _age(0) {}
	Test1(std::string name, int age) : Test(name), _age(age) {}
	std::shared_ptr<Test> clone() const override
	{
		return std::make_shared<Test1>(_name, _age);
	}
};

int main()
{
	std::vector<std::shared_ptr<Test>> v(3);

	for (int i = 0; i < 3; i++)
	{
		v[i] = std::make_shared<Test1>("Misha", 45);
	}

	Test1 asd = v[1]->clone();

	for (int i = 0; i < 3; i++)
	{
		v[i]->Print();
	}

}


Решил написать метод clone. Но строка Test1 asd = v[1]->clone();. Не работает т.к. нельзя преобразовать из одного типа данных в другой. std::shared_ptr asd = v[1]->clone(); И эта штука тоже не работает. Как можно решить эту проблему?
  • Вопрос задан
  • 93 просмотра
Решения вопроса 1
@MarkusD Куратор тега C++
все время мелю чепуху :)
Типом результата Test::clone является std::shared_ptr<Test>.
Строчка Test1 asd = v[1]->clone(); эквивалентна строчке Test1 asd = std::shared_ptr<Test>{ ... };.
Оператора или конструктора преобразования из std::shared_ptr<Test> у типа Test1 нет. Трансляцию строчка Test1 asd = v[1]->clone(); не пройдет.

Идиома Cloneable служит для того, чтобы позволить копирование действительных объектов не выходя за рамки общего интерфейса и не зная действительного типа клонируемого объекта.
Или ты неправильно понял идиому, или пробуешь неправильно ее использовать.

Когда ты заранее знаешь тип, тебе незачем пользоваться клонированием, потому что ты можешь просто скопировать стандартным способом.
Правильно твоя строчка должна выглядеть так: std::shared_ptr<Test> asd = v[1]->clone();.
Или так:
Test1 asd{ *std::static_pointer_cast<Test1>( v[1] ) };
.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@dima20155
you don't choose c++. It chooses you
В почему это
Test1 asd = v[1]->clone();
Должно работать?
В лучшем случае можно заставить работать такой код.
Test asd = *v[1]->clone();

Аналогично с shared_ptr.
Вы фактически возвращаете указатель на Тест, а не Тест1 (в реализации Тест1 вы создайте умный указатель на Тест1, но возвращаемый тип - умный указатель на Тест, отсюда и все проблемы. Если вы уверены, что в этом векторе лежит именно Тест1, то либо dynamic каст (что лучше) либо reinterpret (что хуже, но иногда тоже можно) делайте.

Не очень понимаю зачем вам в принципе этот метод клон нужен, чем вас не устроил копирующий конструктор?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы