无法调用纯抽象基 class 重载
Unable to call pure abstract base class overload
为什么以下代码无法编译,我该怎么办?它不应该找到基class中声明的纯抽象方法吗?
#include <string>
using namespace std::string_literals;
struct A
{
virtual void func1(int) = 0;
virtual void func1(std::string) = 0;
};
struct B : A
{
void func1(int) override
{
func1("bla"s);
}
};
struct C : B
{
void func1(std::string) override
{
}
};
error C2664: 'void B::func1(int)': cannot convert argument 1 from 'std::string' to 'int'
提前致谢,
马丁
编辑链接器错误!
如果有三个文件:
文件test.h
#include <string>
using namespace std::string_literals;
struct A
{
virtual void func1(int) = 0;
virtual void func1(std::string) = 0;
};
struct B : A
{
void func1(int) override
{
A::func1("bla"s);
}
};
struct C : B
{
void func1(std::string) override;
};
文件test.cpp
void C::func1(std::string)
{
}
文件main.cpp
int main()
{
C c;
return 0;
}
这导致
错误LNK2019未解析的外部符号“"public: virtual void __thiscall A::func1(class std::basic_string,class std::allocator >)" (?func1@A@@UAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator @D@2@@std@@@Z)”在函数中“"public: virtual void __thiscall B::func1(int)"
我正在使用 Visual C++ v140。
适用于 using A::func1;
。有什么不同?
B
对 func1
的实现隐藏了 A
的其他两个重载。您可以通过以下方式将它们导入回 B
的界面:
struct B
{
using A::func1;
/* ... */
};
在 general 中,您也可以直接调用基础 class' 重载:
void /*B::*/func1(int) override
{
A::func1("bla"s);
}
这将准确地调用基础class的版本,但是,不是的压倒性变体,但是在在给定的情况下,A
的变体是纯虚拟的(即不存在),因此我们不能在这里应用这种方法。
您与 C
有同样的问题 - 这将无法编译:
C c;
c.func1(123);
名称查找发生在重载解析之前,并且查找在找到第一个匹配项的范围内停止。
您可以使用 using
:
将所有重载引入派生 class 的范围
struct B : A
{
using A::func1; // Make the string overload available trough B's interface.
void func1(int) override
{
func1("bla"s);
}
};
struct C : B
{
using B::func1; // Make the int overload available through C's interface.
void func1(std::string) override
{
}
};
如果您调用 A::func1(std::string)
并且 为其提供实现,您的代码也会编译;
struct A
{
virtual void func1(int) = 0;
virtual void func1(std::string) = 0;
};
// Yes, you can provide an implementation for a pure virtual function.
void A::func1(std::string) {}
struct B : A
{
void func1(int) override
{
A::func1("bla"s);
}
};
但是您可能想要使用的这段代码不会:
void foo(B* b)
{
b->func1("blargh"s);
}
为什么以下代码无法编译,我该怎么办?它不应该找到基class中声明的纯抽象方法吗?
#include <string>
using namespace std::string_literals;
struct A
{
virtual void func1(int) = 0;
virtual void func1(std::string) = 0;
};
struct B : A
{
void func1(int) override
{
func1("bla"s);
}
};
struct C : B
{
void func1(std::string) override
{
}
};
error C2664: 'void B::func1(int)': cannot convert argument 1 from 'std::string' to 'int'
提前致谢, 马丁
编辑链接器错误!
如果有三个文件:
文件test.h
#include <string>
using namespace std::string_literals;
struct A
{
virtual void func1(int) = 0;
virtual void func1(std::string) = 0;
};
struct B : A
{
void func1(int) override
{
A::func1("bla"s);
}
};
struct C : B
{
void func1(std::string) override;
};
文件test.cpp
void C::func1(std::string)
{
}
文件main.cpp
int main()
{
C c;
return 0;
}
这导致
错误LNK2019未解析的外部符号“"public: virtual void __thiscall A::func1(class std::basic_string,class std::allocator >)" (?func1@A@@UAEXV?$basic_string@DU?$char_traits@D@std@@V?$allocator @D@2@@std@@@Z)”在函数中“"public: virtual void __thiscall B::func1(int)"
我正在使用 Visual C++ v140。
适用于 using A::func1;
。有什么不同?
B
对 func1
的实现隐藏了 A
的其他两个重载。您可以通过以下方式将它们导入回 B
的界面:
struct B
{
using A::func1;
/* ... */
};
在 general 中,您也可以直接调用基础 class' 重载:
void /*B::*/func1(int) override
{
A::func1("bla"s);
}
这将准确地调用基础class的版本,但是,不是的压倒性变体,但是在在给定的情况下,A
的变体是纯虚拟的(即不存在),因此我们不能在这里应用这种方法。
您与 C
有同样的问题 - 这将无法编译:
C c;
c.func1(123);
名称查找发生在重载解析之前,并且查找在找到第一个匹配项的范围内停止。
您可以使用 using
:
struct B : A
{
using A::func1; // Make the string overload available trough B's interface.
void func1(int) override
{
func1("bla"s);
}
};
struct C : B
{
using B::func1; // Make the int overload available through C's interface.
void func1(std::string) override
{
}
};
如果您调用 A::func1(std::string)
并且 为其提供实现,您的代码也会编译;
struct A
{
virtual void func1(int) = 0;
virtual void func1(std::string) = 0;
};
// Yes, you can provide an implementation for a pure virtual function.
void A::func1(std::string) {}
struct B : A
{
void func1(int) override
{
A::func1("bla"s);
}
};
但是您可能想要使用的这段代码不会:
void foo(B* b)
{
b->func1("blargh"s);
}