单一定义规则规定:
在整个程序中,一个对象或非内联函数不能有多个定义。(来自维基百科)
好吧,我知道如果在头文件中定义了一个成员函数,它就会被隐式内联,并且可以使用 ODR。
但是虚函数呢?我们知道,如果一个虚函数被多态调用,它就不能被内联。如果在头文件中定义了这样的虚函数,那会违反 ODR 吗?
例如:
//derived.hpp
#include <iostream>
class Base {
public:
virtual ~Base() {}
virtual void vfunc() {
std::cout << "Base::vfunc()\n";
}
};
class Derived : public Base {
public:
virtual ~Derived() {}
virtual void vfunc() {
std::cout << "Derived::vfunc()\n";
}
};
//foo.cpp
#include "derived.hpp"
void func() {
Base* ptr = new Derived();
ptr->vfunc(); //polymorphic call, can't be inlined
delete ptr;
ptr = new Base();
ptr->vfunc();
delete ptr;
}
//main.cpp
#include "derived.hpp"
int main() {
Base* ptr = new Derived();
ptr->vfunc(); //polymorphic call, can't be inlined
delete ptr;
ptr = new Base();
ptr->vfunc();
delete ptr;
return 0;
}
我很好奇:
vfunc(and dtor) 在 foo.cpp 和 main.cpp 中都被多态调用(不是内联),这意味着它在整个程序中定义了两次,所以它违反了 ODR,不是吗?它是如何编译的(链接)?
我刚刚看到:
不止一个定义
在某些情况下,可以有多个类型或模板的定义。由多个头文件和源文件组成的程序通常具有多个类型的定义,但每个翻译单元不超过一个定义。如果一个程序包含多个类型的定义,那么每个定义必须是等价的(也取自维基百科)
是什么certain cases
?上述情况是否属于其中之一?