一定义规则指出:
在整个程序中,一个对象或非内联函数不能有多个定义。(来自维基百科)
嗯,我知道如果成员函数在头文件中定义,它会被隐式地内联,并且符合ODR。
但是虚函数呢?我们知道如果一个虚函数以多态方式调用,它就不能被内联。如果这样的虚函数在头文件中被定义,那么是否会违反ODR?
例如:
在整个程序中,一个对象或非内联函数不能有多个定义。(来自维基百科)
嗯,我知道如果成员函数在头文件中定义,它会被隐式地内联,并且符合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;
}
我很好奇:
在foo.cpp和main.cpp中,vfunc(和dtor)以多态方式调用(不是内联),这意味着它在整个程序中被定义了两次,所以它违反了ODR,是吗?它该如何编译(链接)?
我刚刚看到:
多余的定义
在某些情况下,类型或模板可能有多个定义。由多个头文件和源文件组成的程序通常会有多个类型定义,但每个翻译单位只有一个定义。如果程序包含一个类型的多个定义,则每个定义必须等效(也取自维基百科)。
什么是“某些情况”?上述情况是否属于此类情况之一?
inline
和内联的注释 :-) - Arne Mertz