Извините, я довольно зеленый с C ++ это возможно?
У меня есть суперкласс с огромным конструктором, поэтому я создал статический конструктор фабричного типа, который выполнит некоторую работу, а затем вернет новый ParametricShape (бла-бла-бла …);
class ParametricShape: public ModelView{
public:
//actually has 15 arguments didn't want to type them all up
ParametricShape(func x, funcy, funcz, float lu, float hu, float lv, float hv, int sv, int su);
static ParametricShape* makeDonutShape(float);
}
Позже я хочу использовать этот статический метод в расширенном классе.
class Donut : public ParametricShape{
Donut();
}
Donut::Donut(){
this = ParametricShape::makeDonut(1.0f);
}
Это то, что я пытаюсь сделать, я возился с различными конструкторами копирования, а что нет, и получал всевозможные ошибки. В настоящее время он просто говорит: lvalue требуется как левый операнд присваивания. Спасибо за любую помощь!
Хотя я согласен с большинством других ответов, в вашем случае вам не нужен классический заводской шаблон. Как я вижу, вы хотите иметь один класс, который описывает фигуру с параметрическими функциями для их геометрии. Вы хотите предоставить удобные методы для создания этих фигур для некоторых особых случаев, таких как «пончик». Если вы не хотите использовать какие-либо другие функции наследования, такие как перегрузка некоторых методов для специальных типов фигур, вы можете просто удалить другие классы, такие как Donut
и просто используйте функции «maker» в вашем клиентском коде.
Возможность сделать код по-прежнему более объектно-ориентированным (и сохранить подклассы и использовать их конструкторы в клиентском коде), вы можете переписать функции создателя в функции инициализации, как я хочу их вызывать. Обратите внимание, что я также представил конструктор по умолчанию, который нам нужен в специализированных классах:
class ParametricShape {
func x, y, z;
...
public:
ParametricShape();
ParametricShape(func x, func y, func z, ...);
protected:
void initDonutShape(float);
};class Donut : public ParametricShape {
public:
Donut(float radius) :
ParametricShape() // call default constructor of ParametricShape
{
initDonutShape(radius); // initialize functions for "Donut"}
};
Теперь реализовать initDonutShape
метод как это:
void ParametricShape::initDonutShape(float radius) {
// set the parametric functions
x = ...
y = ...
z = ...
}
а не возвращать новый экземпляр ParametricShape
,
Вы не можете назначить на «это». Это константный тип.
Тип указателя this для функции-члена класса типа X,
является X * const.
В шаблоне фабричного дизайна у вас обычно есть отдельный класс, заботящийся о создании новых экземпляров. Это отделение создания объекта от класса его самого — вот и весь смысл этого шаблона проектирования. Смотрите это обсуждение о том, как реализовать это в C ++
Вот типичная «фабричная» модель:
#include <memory>
struct Shape
{
enum Type { Donut, Sphere, Teapot };
static std::unqiue_ptr<Shape> make(Type type);
virtual ~Shape() = default;
// ...
};
struct Donut : Shape
{
// ...
};
std::unique_ptr<Shape> Shape::make(Shape::Type type)
{
switch(type)
{
case Donut: return { new Donut; }
default: return { };
}
}
Использование:
auto p = Shape::make(Shape::Donut);
Да, это возможно… 🙂
#include <new>
Donut::Donut() {
this->~Donut();
new (this) ( *((Donut*) ParametricShape::makeDonut(1.0f)) );
}
убедитесь, что у вас есть определенный конструктор копирования,
this->~Donut();
гарантирует, что все, выделенное через конструкторы по умолчанию, будут удалены, а вторая строка new (this) ( (Donut*) ParametricShape::makeDonut(1.0f) );
сначала создает объект-пончик, переосмысливает его как Donut [будьте осторожны, здесь нет проблем, потому что Donut не определяет переменную, кроме его родителя], и вызывает конструктор копирования …
new (this) не будет выделять новое хранилище из памяти, он просто вызывает конструктор 🙂