У меня есть небольшой пример шаблона проектирования Factory, и меня интересует эта часть:
std::make_unique< A >(*this)
... особенно *this.
Означает ли это, что метод clone() возвращает std::unique_ptr, который указывает на член фабричного класса?
И createInstance() всегда возвращает один и тот же член класса Factory?
Я просто не понимаю, что должен делать std::make_unique< A >(*this), потому что A имеет конструктор std::string, а не указатель на себя.
class Base {
public:
virtual ~Base() {}
virtual std::unique_ptr<Base> clone() = 0;
virtual void print() = 0;
};
class A: public Base {
std::string name_;
public:
A(std::string name ){name_ = name;};
std::unique_ptr<Base> clone() override{
return std::make_unique<A>(*this);
};
void print( ) override{
std::cout << "Class A: " << name_;
};
virtual ~A(){};
};
class Factory{
std::unique_ptr<A> type = std::make_unique<A>("MyName");
public:
std::unique_ptr<Base> createInstance(){
return type->clone();
}
};
int main(){
Factory factory;
auto instance = factory.createInstance();
instance->print();
}





std::make_unique<A>(*this) в основном эквивалентен:
unique_ptr<A>(new A(*this))
В clone()*this является lvalue-ссылкой на A, поэтому вы конструируете A из (lvalue-reference to) A (внутри std::make_unique), поэтому вы используете неявно объявленный копирующий конструктор A:
A(A const&);
Таким образом, вы фактически делаете копию текущего объекта во вновь выделенный блок памяти.
Поскольку createInstance использует clone(), вы создаете «копию» type каждый раз, когда вызываете createInstance.
@curiousguy В C++ нет такой вещи, как ссылочные типы lvalue? Если хочешь быть педантичным, возможно, добавь подробностей в свои комментарии, я пока не умею читать мысли.
@curiousguy Не то, что говорится в стандарте: eel.is/c++draft/basic.types / eel.is/c++draft/dcl.ref Если вы не рассматриваете ссылки как тип, это означает, что вы не можете объявить переменные, которые являются ссылками, используйте ссылочные типы в качестве аргументов шаблона.
"не считайте ссылки типом" Я такого не писал. Ссылочный тип - это тип. *this не является ссылкой.
@curiousguy "Нет ссылочных типов". против «Ссылочный тип - это тип»? Который из? Тип *this - это именно A&, вы можете протестировать его на любом совместимом компиляторе, decltype(*this) - это именно A&. «Унарный оператор * выполняет косвенное обращение: выражение, к которому он применяется, должно быть указателем на тип объекта или указателем на тип функции, а результатом является lvalue, относящееся к объекту или функции, на которые указывает выражение». (eel.is/c++draft/expr.unary.op#1)
Неа. В C или C++ нет ссылки на тип.
@curiousguy Трех ссылок на стандартные упоминания ссылочных типов недостаточно? Может быть, вам стоит указать мне на более высокие места, указывающие на то, что в C++ нет ссылок? Вы написали 4 комментария, два из которых противоречат друг другу («Нет ссылочных типов», "Ничто не относится к типу ссылки", «Ссылочный тип - это как тип»), без каких-либо подтверждений вашего высказывания. Я заканчиваю этот разговор, пока вы не посмотрите на три ссылки, которые я поместил в своих предыдущих комментариях.
И все же *this по-прежнему не является ссылкой, и ни одна из ваших нерелевантных ссылок не говорит, что что-то «типа A &» на C или C++
@curiousguy decltype(*this) - это A&, поэтому *this относится к типу A&, так же как decltype(0) - это int, поэтому 0 относится к типу int. - Может быть, вы хотели бы указать, какой тип *this находится в вашем мире?
*p имеет тот же тип в C или C++, и это не ссылка. Это T, если p имеет тип T*. Прочтите любой пример в std, он никогда не говорит: int i; (i); // has int& type"Мало трех ссылок на стандартные упоминания ссылочных типов?" Вы читаете текст, на который ссылаетесь?
@curiousguy Так как мне нужно поспать, я перефразировал предложение на "*this - это lvalue-ссылка на A", надеюсь, вы останетесь довольны.
"не указатель на себя" Вы пропустили оператор разыменования в
*this? ;)