Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么';这不提供多定义错误吗?_C++_Destructor - Fatal编程技术网

C++ 为什么';这不提供多定义错误吗?

C++ 为什么';这不提供多定义错误吗?,c++,destructor,C++,Destructor,为了方便起见,我曾经内联编写虚拟析构函数的定义,尽管它并不正确。今天我决定做一个小测试来了解发生了什么 哑巴 #ifndef DUMMY_HEADER #define DUMMY_HEADER #include <iostream> class Dummy { public: virtual ~Dummy() {std::cout << "dummy destroyed" << std::endl;} }; class DummyEx :

为了方便起见,我曾经内联编写虚拟析构函数的定义,尽管它并不正确。今天我决定做一个小测试来了解发生了什么

哑巴

#ifndef DUMMY_HEADER
#define DUMMY_HEADER

#include <iostream>

class Dummy
{
public:
        virtual ~Dummy() {std::cout << "dummy destroyed" << std::endl;}
};

class DummyEx : public Dummy
{
public:
        virtual ~DummyEx() {std::cout << "DummyEx destroyed" << std::endl;}
};

#endif
main.cpp

#include "dummy.h"

void deleteDummy(Dummy* dummy);

int main()
{
        Dummy* dummy = new DummyEx();
        delete dummy;
        dummy = new DummyEx();
        deleteDummy(dummy);
        return 0;
}
我用
g++-c deleter.cpp
编译了
deleter.cpp
,得到了
deleter.o

我用
g++-c main.cpp
编译了
main.cpp
,得到了
main.o

我用
g++deleter.o main.o
链接了对象文件,得到了
a.out

当我执行
a.out
时,输出与预期一样,来自
Dummy
DummyEx
析构函数的两个cout都在那里


但是,编译后的析构函数定义指向哪个对象文件?它们不可能同时指向两个对象文件,因为我在链接时没有收到多定义错误。此外,编译器也没有内联析构函数,因为虚拟函数被正确调用。

,所以在链接时不会遇到“多个定义”错误。

这些定义是隐式
内联的,允许多个定义存在,只要它们在词汇上相同。

一个定义规则不适用于内联函数。析构函数是隐式内联的。语言规范只是说这必须起作用。你是在问编译器/链接器是如何做到这一点的吗?ODR确实适用于内联函数,但它规定如果有多个定义,它们必须具有完全相同的定义。任何内联函数都可以在多个对象文件中具有定义,只要它们相同?如果是的话,它解释了这一点。
#include "dummy.h"

void deleteDummy(Dummy* dummy);

int main()
{
        Dummy* dummy = new DummyEx();
        delete dummy;
        dummy = new DummyEx();
        deleteDummy(dummy);
        return 0;
}