ura*_*ray 6 c++ linker-errors pure-virtual operator-keyword
为什么如果我们在基类中有纯虚拟赋值运算符,那么我们在派生类上实现该运算符,它会在基类上给出链接器错误?
目前我在http://support.microsoft.com/kb/130486上只有以下说明,它说该行为是设计的,因为正常的继承规则不适用.
我不清楚,为什么它会通过设计产生链接器错误?有人可以给我更明确的解释吗?
编辑:添加了我发生错误的简化代码:
class __declspec(dllexport) BaseClass {
public:
int memberA;
virtual BaseClass& operator=(const BaseClass& rhs) = 0;
};
class __declspec(dllexport) DerivedClass : public BaseClass {
public:
int memberB;
DerivedClass():memberB(0) {}
virtual BaseClass& operator=(const BaseClass& rhs) {
this->memberA = rhs.memberA;
this->memberB = 1;
return *this;
}
};
int main(void)
{
DerivedClass d1;
DerivedClass d2;
BaseClass* bd1 = &d1;
BaseClass* bd2 = &d2;
*bd1 = *bd2;
}
Run Code Online (Sandbox Code Playgroud)
如果没有 __declspec(dllexport)和/或没有基类上的纯虚拟运算符=声明,代码将编译时没有错误.
在没有__declspec(dllexport)赋值之后*bd1 = *bd2;,d1 :: memberB是1,但是__declspec(dllexport)d1 :: memberB保持不变
在__declspec(dllexport)没有纯虚拟声明的情况下,在分配之后*bd1 = *bd2;,d1 :: memberB保持不变
operator =不是继承的.您的代码在C++中毫无意义,因此编译器可以自由地发出它们想要的任何错误.
从您指向的知识库文章:http://support.microsoft.com/kb/130486
由于不继承operator =,因此基类中的operator =的任何声明都是未使用且不必要的.不要在基类中声明operator =.
这可能只是他们如何编译的副作用,他们只是让你知道他们不认为它是一个bug,所以没有必要修复它."通过设计"并不一定意味着他们明确地决定这个链接器错误是正确的错误消息给出这种情况 - 代码是错误的,你得到一个错误,所以从他们的角度来看 - 他们是完成.
从标准第12.8节开始:
13类X的隐式定义的复制赋值运算符执行其子对象的成员分配.首先按照它们在base-specifier-list中的声明顺序分配X的直接基类,然后按照它们在类定义中声明的顺序分配X的直接非静态数据成员. .每个子对象都以适合其类型的方式分配:- 如果子对象是类类型,则使用该类的复制赋值运算符(就像通过显式限定;即忽略更多派生类中的任何可能的虚拟覆盖函数);
子类使用隐式定义的复制赋值运算符,并且没有基类的复制赋值运算符的定义,但它已声明,因此您会收到链接错误而不是编译错误.