Использование этого * в make_unique

У меня есть небольшой пример шаблона проектирования 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();
}

"не указатель на себя" Вы пропустили оператор разыменования в *this? ;)

curiousguy 28.05.2018 19:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
1
1 544
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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? Если хочешь быть педантичным, возможно, добавь подробностей в свои комментарии, я пока не умею читать мысли.

Holt 28.05.2018 19:44

@curiousguy Не то, что говорится в стандарте: eel.is/c++draft/basic.types / eel.is/c++draft/dcl.ref Если вы не рассматриваете ссылки как тип, это означает, что вы не можете объявить переменные, которые являются ссылками, используйте ссылочные типы в качестве аргументов шаблона.

Holt 28.05.2018 21:29

"не считайте ссылки типом" Я такого не писал. Ссылочный тип - это тип. *this не является ссылкой.

curiousguy 28.05.2018 22:03

@curiousguy "Нет ссылочных типов". против «Ссылочный тип - это тип»? Который из? Тип *this - это именно A&, вы можете протестировать его на любом совместимом компиляторе, decltype(*this) - это именно A&. «Унарный оператор * выполняет косвенное обращение: выражение, к которому он применяется, должно быть указателем на тип объекта или указателем на тип функции, а результатом является lvalue, относящееся к объекту или функции, на которые указывает выражение». (eel.is/c++draft/expr.unary.op#1)

Holt 28.05.2018 22:05

Неа. В C или C++ нет ссылки на тип.

curiousguy 28.05.2018 22:17

@curiousguy Трех ссылок на стандартные упоминания ссылочных типов недостаточно? Может быть, вам стоит указать мне на более высокие места, указывающие на то, что в C++ нет ссылок? Вы написали 4 комментария, два из которых противоречат друг другу («Нет ссылочных типов», "Ничто не относится к типу ссылки", «Ссылочный тип - это как тип»), без каких-либо подтверждений вашего высказывания. Я заканчиваю этот разговор, пока вы не посмотрите на три ссылки, которые я поместил в своих предыдущих комментариях.

Holt 28.05.2018 22:20

И все же *this по-прежнему не является ссылкой, и ни одна из ваших нерелевантных ссылок не говорит, что что-то «типа A &» на C или C++

curiousguy 28.05.2018 22:26

@curiousguy decltype(*this) - это A&, поэтому *this относится к типу A&, так же как decltype(0) - это int, поэтому 0 относится к типу int. - Может быть, вы хотели бы указать, какой тип *this находится в вашем мире?

Holt 28.05.2018 22:39
*p имеет тот же тип в C или C++, и это не ссылка. Это T, если p имеет тип T*. Прочтите любой пример в std, он никогда не говорит: int i; (i); // has int& type
curiousguy 28.05.2018 22:42

"Мало трех ссылок на стандартные упоминания ссылочных типов?" Вы читаете текст, на который ссылаетесь?

curiousguy 28.05.2018 22:44

@curiousguy Так как мне нужно поспать, я перефразировал предложение на "*this - это lvalue-ссылка на A", надеюсь, вы останетесь довольны.

Holt 28.05.2018 22:59

Другие вопросы по теме