为什么非纯虚方法一定要定义在baseclass中?
Why does non-pure virtual method have to be defined in base class?
在这种特殊情况下,为什么我必须在基 class 中定义非纯虚方法以避免链接器错误?
这给出了链接器错误:
class A
{
public:
virtual ~A(){}
virtual void foo() = 0;
virtual void bar();
};
class B : public A
{
public:
void foo()
{
}
void bar()
{
}
};
int main()
{
B b;
}
输出:
/tmp/cc5E8Tit.o: In function `A::~A()':
:(.text._ZN1AD2Ev[_ZN1AD5Ev]+0x13): undefined reference to `vtable for
A' /tmp/cc5E8Tit.o:(.rodata._ZTI1B[_ZTI1B]+0x10): undefined reference
to `typeinfo for A' collect2: error: ld returned 1 exit status
但是如果我在 class A
中定义 bar 方法,它链接就可以了:
class A
{
public:
virtual ~A(){}
virtual void foo() = 0;
virtual void bar(){}
};
class B : public A
{
public:
void foo()
{
}
void bar()
{
}
};
int main()
{
B b;
}
...没有链接器错误。
这是为什么?
答案就在定义本身。如果一个函数没有定义,它就是纯虚函数。然后,如果您不将其标记为纯虚拟,则必须定义它。这是 C++
语言的限制。
来自 C++11 标准:
10.3 Virtual functions
11 A virtual function declared in a class shall be defined, or declared pure (10.4) in that class, or both; but no diagnostic is required (3.2).
定义一个纯虚函数是可以的,但没有必要。
如果声明为纯虚函数但未声明为纯虚函数,则需要定义虚函数
即使语言不需要它,链接器也会抱怨,这很好。
R Sahu 已经提供了与此相关的标准引用,我将提供稍微更长的解释为什么会发生错误——有时如果不使用函数你可以不定义它们,但在这种情况下不是。
总是使用虚函数。它们的 地址 用于虚拟 tables,虚拟 tables 是为每个 class 构建的,具有虚拟功能,用于动态调度。
链接器发出错误,因为 base class A
构造函数设置指向 base class virtual table 的指针,virtual table 包含指向 bar
并且链接器找不到 bar
成员函数的定义来查找其地址。
在这种特殊情况下,为什么我必须在基 class 中定义非纯虚方法以避免链接器错误?
这给出了链接器错误:
class A
{
public:
virtual ~A(){}
virtual void foo() = 0;
virtual void bar();
};
class B : public A
{
public:
void foo()
{
}
void bar()
{
}
};
int main()
{
B b;
}
输出:
/tmp/cc5E8Tit.o: In function `A::~A()':
:(.text._ZN1AD2Ev[_ZN1AD5Ev]+0x13): undefined reference to `vtable for
A' /tmp/cc5E8Tit.o:(.rodata._ZTI1B[_ZTI1B]+0x10): undefined reference
to `typeinfo for A' collect2: error: ld returned 1 exit status
但是如果我在 class A
中定义 bar 方法,它链接就可以了:
class A
{
public:
virtual ~A(){}
virtual void foo() = 0;
virtual void bar(){}
};
class B : public A
{
public:
void foo()
{
}
void bar()
{
}
};
int main()
{
B b;
}
...没有链接器错误。
这是为什么?
答案就在定义本身。如果一个函数没有定义,它就是纯虚函数。然后,如果您不将其标记为纯虚拟,则必须定义它。这是 C++
语言的限制。
来自 C++11 标准:
10.3 Virtual functions
11 A virtual function declared in a class shall be defined, or declared pure (10.4) in that class, or both; but no diagnostic is required (3.2).
定义一个纯虚函数是可以的,但没有必要。
如果声明为纯虚函数但未声明为纯虚函数,则需要定义虚函数
即使语言不需要它,链接器也会抱怨,这很好。
R Sahu 已经提供了与此相关的标准引用,我将提供稍微更长的解释为什么会发生错误——有时如果不使用函数你可以不定义它们,但在这种情况下不是。
总是使用虚函数。它们的 地址 用于虚拟 tables,虚拟 tables 是为每个 class 构建的,具有虚拟功能,用于动态调度。
链接器发出错误,因为 base class A
构造函数设置指向 base class virtual table 的指针,virtual table 包含指向 bar
并且链接器找不到 bar
成员函数的定义来查找其地址。