Возможные реализации для решения конкретных задач на С++

Прототип. Идиома NVI (Non-Virtual Interface)

class Car
{
public:
	virtual ~Car() = default;
	unique_ptr<Car> clone();

private:
	virtual unique_ptr<Car> doClone() = 0;
};
# include <iostream>
# include <memory>
# include <exception>

using namespace std;

int main()
{
	try
	{
		shared_ptr<Car> luxsedan = make_shared<LuxurySedan>();
		User{}.use(luxsedan);
	}
	catch (exception& err)
	{
		cout << err.what() << endl;
	}
}

Прототип (Prototype). «Статический полиморфизм» (CRTP)

class Base
{
public:
    virtual ~Base() = default;

    virtual unique_ptr<Base> clone() const = 0;
    virtual ostream& print(ostream& os) const = 0;
};
# include <iostream>
# include <memory>
# include <concepts>

using namespace std;

int main()
{
    unique_ptr<Base> vehicle = make_unique<Car>(10);
    User{}.use(vehicle);
}

Прототип (Prototype). «Статический полиморфизм» (CRTP) и множественное наследование

class Base
{
public:
    virtual ~Base() = default;

    unique_ptr<Base> clone() const;
    virtual ostream& print(ostream& os) const = 0;
};


unique_ptr<Base> Base::clone() const
{
    return dynamic_cast<const BaseCloner*>(this)->doClone();
}


ostream& operator <<(ostream& os, const unique_ptr<Base>& obj)
{
    return obj->print(os);
}
# include <iostream>
# include <memory>
# include <concepts>

using namespace std;

int main()
{
    unique_ptr<Base> vehicle = make_unique<Car>(10);
    User{}.use(vehicle);
}

Прототип (Prototype). Ковариантный виртуальный метод. Идиомы CRTP и NVI

struct NullType { };

template<typename Derived, typename Base = NullType>
struct Cloner : public Base
{
    virtual ~Cloner() = default;

    unique_ptr<Derived> clone() const
    {
        return unique_ptr<Derived>(static_cast<Derived*>(this->doClone()));
    }

protected:
    virtual Cloner* doClone() const
    {
        return new Derived(*static_cast<const Derived*>(this));
    }
};
# include <iostream>
# include <memory>

using namespace std;

int main()
{
    unique_ptr<Car> vehicle = make_unique<Sedan>();

    User{}.use(vehicle);
}

Last updated

Was this helpful?