如何在编译器隐式删除它时修复“尝试引用已删除的函数”

问题描述 投票:0回答:1

我试图创建一个泛型类,可以代表其最基本形式的任何对象,位。为此,我创建了一个字符数组的联合(基本上是字节)和字符组成的对象。不幸的是,在建造时,我的工会发出了一个奇怪的警告和错误。

警告:“析构函数被隐式定义为已删除。”

错误:“正在尝试引用已删除的功能。”

(两者都出现在我的工会定义之后的行上)

我知道你可以为结构,类和联合创建自定义析构函数,但是如果你没有释放动态内存,则没有必要,对吗?然而,某种程度上,我从未定义过的析构函数会被自动调用,编译器会隐式删除它。因此错误。

我尝试的下一件事是在我的工会中定义一个析构函数;它什么也没做,因为我从来没有要求操作系统获得额外的记它再次被删除。我需要弄清楚为什么编译器正在删除我的函数,然后在删除它后尝试调用它时导致错误。

我试图在Microsoft visual studio列表中查找此错误,它提出的是不使构造函数公开会导致此错误。另外,在网上查看我发现复制构造函数通常是导致错误的原因,因为它从未被定义过。所以我通过创建一个自己的类并使用copy constructor =来测试它。它运行得很好,但在尝试将其与我的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等)之外的任何对象制作时失败。任何有关此事的澄清将不胜感激。

c++ templates destructor implicit
1个回答
0
投票

以下是@Miles Budnek的完美解决方案。非常感谢您的信息,我从来不知道这是c ++中的功能。

“reinterpret_cast(&object)是一种定义良好的方法来访问组成对象的字节(即使它对std :: string这样的东西不是很有用)。通过union的类型惩罚没有明确定义。 - Miles Budnek “

© www.soinside.com 2019 - 2024. All rights reserved.