gpt4 book ai didi

c++ - 重载抽象运算符时出现 Clang 链接器错误=

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:33:57 25 4
gpt4 key购买 nike

VisualStudio 2013 编译器可以很好地处理以下代码,但 clang 5.0 和 6.2 给我一个链接器错误:

#include <memory>

using namespace::std;

class IBase
{
public:
virtual IBase& operator=(const IBase& other) = 0;
};

class Base : virtual public IBase
{
public:
Base& operator=(const IBase& other) override
{
const Base& b = dynamic_cast<const Base&>(other);
return *this = b;
}

virtual Base& operator=(const Base& other)
{
return *this;
}
};

class IDerived : virtual public IBase
{
};

class Derived : public IDerived, public Base
{
public:
using Base::operator=;

};

int main(int argc, const char * argv[]) {
shared_ptr<Derived> d1 = make_shared<Derived>();
shared_ptr<Derived> d2 = make_shared<Derived>();
*d2 = *d1;
}

这是构建日志输出:

Ld /Users/Jennifer/Library/Developer/Xcode/DerivedData/Operator-bjjgcoxcziyegjgmazknrandutqz/Build/Products/Debug/Oper normal x86_64
cd /Users/Jennifer/Documents/Operator
export MACOSX_DEPLOYMENT_TARGET=10.9
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -L/Users/Jennifer/Library/Developer/Xcode/DerivedData/Operator-bjjgcoxcziyegjgmazknrandutqz/Build/Products/Debug -F/Users/Jennifer/Library/Developer/Xcode/DerivedData/Operator-bjjgcoxcziyegjgmazknrandutqz/Build/Products/Debug -filelist /Users/Jennifer/Library/Developer/Xcode/DerivedData/Operator-bjjgcoxcziyegjgmazknrandutqz/Build/Intermediates/Operator.build/Debug/Oper.build/Objects-normal/x86_64/Oper.LinkFileList -mmacosx-version-min=10.9 -stdlib=libc++ -Xlinker -dependency_info -Xlinker /Users/Jennifer/Library/Developer/Xcode/DerivedData/Operator-bjjgcoxcziyegjgmazknrandutqz/Build/Intermediates/Operator.build/Debug/Oper.build/Objects-normal/x86_64/Oper_dependency_info.dat -o /Users/Jennifer/Library/Developer/Xcode/DerivedData/Operator-bjjgcoxcziyegjgmazknrandutqz/Build/Products/Debug/Oper

Undefined symbols for architecture x86_64:
"IBase::operator=(IBase const&)", referenced from:
IDerived::operator=(IDerived const&) in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

IBase::operator=(IBase const&)定义在Base中,Derived继承自,Derived 使用 Base::operator=,因此它应该Derived 定义,而不是被默认赋值运算符覆盖。

我找到的一个解决方案是删除 IBase::operator= 方法,但这并不理想,因为它是任何继承类都需要实现的方法。

有谁知道区别是什么以及如何解决?如果可能,我想保留 IBase::operator= 方法。

最佳答案

问题是 using 声明不算作用户声明的赋值运算符[namespace.udecl]:

4 - [...] If an assignment operator brought from a base class into a derived class scope has the signature of a copy/move assignment operator for the derived class (12.8), the using-declaration does not by itself suppress the implicit declaration of the derived class assignment operator [...]

(在任何情况下,使用 Base::operator= 都会为您提供参数类型为 Base const& 的赋值运算符,这不是符合条件的参数类型之一复制赋值运算符[class.copy]/17 - TT&T const&等)

因为 Derived 没有用户声明的复制赋值运算符,一个是自动生成的,最终调用 IDerived::operator= 调用 IBase::运算符=。请注意,自动生成的复制赋值运算符会调用子对象复制赋值运算符,而忽略虚拟覆盖:

Each subobject is assigned in the manner appropriate to its type:

  • if the subobject is of class type, as if by a call to operator= with the subobject as the object expression and the corresponding subobject of x as a single function argument (as if by explicit qualification; that is, ignoring any possible virtual overriding functions in more derived classes); [...]

一个解决方法是写:

    Base& operator=(Derived const& other) { return Base::operator=(other); }

请注意,MSVC 2015 拒绝您的代码,但适用于上述修复:

main.cpp(36): warning C4250: 'Derived': inherits 'Base::Base::operator =' via dominance
main.cpp(14): note: see declaration of 'Base::operator ='
main.obj : error LNK2019: unresolved external symbol "public: virtual class IBase & __thiscall IBase::operator=(class IBase const &)" (??4IBase@@UAEAAV0@ABV0@@Z) referenced in function "public: class IDerived & __thiscall IDerived::operator=(class IDerived const &)" (??4IDerived@@QAEAAV0@ABV0@@Z)
main.exe : fatal error LNK1120: 1 unresolved externals

关于c++ - 重载抽象运算符时出现 Clang 链接器错误=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34411588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com