Могу ли я создать структуру, которая может быть распределена только динамически? - PullRequest
0 голосов
/ 01 апреля 2020

В C ++ я могу создать структуру, которая может быть распределена только динамически? Я хочу обеспечить способ убедиться, что программист не может статически распределить эту структуру, потому что это приведет к зависанию указателя, поскольку мне нужно использовать содержимое указателя вне его области действия.

Ответы [ 2 ]

5 голосов
/ 01 апреля 2020

Вы можете создать struct частного конструктора, чтобы никто не мог создать из него, а затем создать функцию friend, которая создает динамически размещенный объект и возвращает указатель на него, как показано ниже.

#include <iostream>
struct A{
    ~A() {
        std::cout << "\nA has been destructed";
    }
private:
    A(/*args*/) {
        std::cout << "\nA has been created";
    }
    friend A* creatA(/*args*/);

};
A* creatA(/*args*/){
    return new A(/*args*/);
}

int main()
{
    A* ptr = creatA();
    delete ptr;

}

Это может быть лучше при использовании умных указателей и подсказок @Peter

#include <iostream>
#include <memory>

struct A{
    A(/*args*/) {
        std::cout << "\nA has been created";
    }
    friend std::default_delete<A>;
private:
    ~A() {
        std::cout << "\nA has been destructed";
    }
};

int main()
{
    std::unique_ptr<A> ptr = std::make_unique<A>(/*Args*/);

}
0 голосов
/ 01 апреля 2020

@ asmmo уже объяснил, но я хочу предложить подобное решение в более обобщенном виде с template s. Насколько я знаю, нет языковой функции, которая бы делила классы только на динамическое распределение. Это означает, что наше желаемое поведение должно быть имитировано. Таким образом, решение состоит в том, чтобы сделать конструкторы доступными только для функций, которые динамически распределяют классы.

Возможная реализация:

#include <utility>

template<typename T, typename... Args>
inline T* create( Args&&... args )
{
    return new T { std::forward<Args>( args )... };
}

class foo
{
    private:
        foo() {}
        foo( int ) { }

        template<typename T, typename... Args>
        friend T* create( Args&&... );
};

class bar
{
    private:
        bar() {}
        bar( int ) { }

        template<typename T, typename... Args>
        friend T* create( Args&&... );
};

int main()
{
    auto f1 = create<foo>( 15 );
    auto f2 = create<foo>();
    auto b1 = create<bar>();
    auto b2 = create<bar>( 14 );
}

запуск в режиме онлайн

...