Как исправить «попытку ссылки на удаленную функцию», когда компилятор неявно удалил ее - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь создать универсальный класс, который может представлять любой объект в его самой базовой форме, битах. Для этого я создал объединение массива символов (в основном байтов) и объекта, из которого состоят символы. К сожалению, при сборке я получаю странное предупреждение и ошибку для своего союза.

Предупреждение: «Деструктор был неявно определен как удаленный.»

Ошибка: «Попытка обратиться к удаленной функции.»

(оба встречаются в строке после определения моего союза)

Я знаю, что вы можете создавать собственные деструкторы для структур, классов и объединений, но нет необходимости, если вы не освобождаете динамическую память, правильно? Однако каким-то образом деструктор, который я никогда не определял, вызывается автоматически, и компилятор неявно удаляет его. Отсюда и ошибка.

Следующим, что я попытался, было определение деструктора в моем союзе; это ничего не сделало, потому что я никогда не просил ОС для дополнительной памяти. Это было еще раз удалено. Мне нужно было выяснить, почему компилятор удалял мою функцию, а затем вызывал ошибку при попытке вызвать ее после того, как удалил ее.

Я попытался найти эту ошибку в списке Microsoft Visual Studio, и она пришла к выводу, что недопущение публикации конструктора приведет к этой ошибке. Кроме того, просмотрев онлайн здесь, я обнаружил, что часто конструктор копирования является причиной ошибки, потому что она никогда не определялась. Поэтому я проверил это, создав собственный класс и используя конструктор копирования = для него. Он работал просто отлично, но выдает мне ту же ошибку при попытке использовать его с моим классом typeAsChar. Интересно, что эта ошибка не вызывается, когда я использую свой класс со структурами C по умолчанию, int, double и т. Д.

Вот код, вызывающий проблему.

template <class type>
union typeAsChar
{
    type obj;
    char arr[sizeof(type)];
};

template <class type> 
class wontWork
{
public:

    wontWork() {/* Do nothing, no data entered */}
    wontWork(const type& obj) { foo.obj = obj; }
    ~wontWork() {/* When this goes out of scope, the default
                     destructor of the member 'type' should be called */}

    typeAsChar<type> foo;
};

int main()
{
    double testNum = 12345;
    std::string testStr = "Hello World\n";

    wontWork<std::string> test1(testStr); // has error
    std::cout << test1.foo.obj;

    wontWork<double> test2(testNum); // No error
    std::cout << test2.foo.obj;

        return 0;
}

Как ни странно, он отлично компилируется и работает с wontWork<std::string> закомментированным, но завершается неудачно, когда мой класс сделан с объектом, отличным от стандартных структур c (int, double и т. Д.). Будем весьма благодарны за любые разъяснения по этому вопросу.

1 Ответ

0 голосов
/ 19 апреля 2019

Вот ответ @Miles Budnek, который отлично сработал. Большое спасибо за вашу информацию, я никогда не знал, что это функциональность в C ++.

"reinterpret_cast (& object) - это четко определенный способ доступа к байтам, из которых состоит объект (даже если он не очень полезен для чего-то вроде std :: string). Наказание типов через union не является четко определенным. - Майлз Буднек "

...