C++ 多态性失败
我有一个非常简单的多态性设置:基类和虚方法,派生类重载方法。稍微有点扭曲的是,它们是模板类,基类的方法会导致派生类的编译失败。我认为这不会是一个问题,因为基类的方法是重载的,但显然这是一个问题 为了说明这个问题,我已经尽可能地精简了代码。给你 DspBuffer.hC++ 多态性失败,c++,xcode,templates,polymorphism,C++,Xcode,Templates,Polymorphism,我有一个非常简单的多态性设置:基类和虚方法,派生类重载方法。稍微有点扭曲的是,它们是模板类,基类的方法会导致派生类的编译失败。我认为这不会是一个问题,因为基类的方法是重载的,但显然这是一个问题 为了说明这个问题,我已经尽可能地精简了代码。给你 DspBuffer.h #include <vector> #include <algorithm> #include <cassert> template <class T> class DspBuffe
#include <vector>
#include <algorithm>
#include <cassert>
template <class T>
class DspBuffer {
public:
std::vector<T> buf;
DspBuffer<T>(unsigned size) {buf = std::vector<T>(size);}
virtual void sort() {std::sort(buf.begin(), buf.end());}
};
#include <complex>
#include "DspBuffer.h"
template <class T>
class ComplexDspBuffer : public DspBuffer<T> {
public:
ComplexDspBuffer<T>(unsigned size) : DspBuffer<T>(size) {}
void sort() {assert(false);}
};
#包括
#包括
#包括
模板
DspBuffer类{
公众:
std::载体buf;
DspBuffer(无符号大小){buf=std::vector(大小);}
虚拟空排序(){std::sort(buf.begin(),buf.end());}
};
ComplexDspBuffer.h
#include <vector>
#include <algorithm>
#include <cassert>
template <class T>
class DspBuffer {
public:
std::vector<T> buf;
DspBuffer<T>(unsigned size) {buf = std::vector<T>(size);}
virtual void sort() {std::sort(buf.begin(), buf.end());}
};
#include <complex>
#include "DspBuffer.h"
template <class T>
class ComplexDspBuffer : public DspBuffer<T> {
public:
ComplexDspBuffer<T>(unsigned size) : DspBuffer<T>(size) {}
void sort() {assert(false);}
};
#包括
#包括“DspBuffer.h”
模板
类ComplexDspBuffer:公共DspBuffer{
公众:
ComplexDspBuffer(无符号大小):DspBuffer(大小){}
void sort(){assert(false);}
};
main.cpp
#include "ComplexDspBuffer.h"
int main(int argc, char **argv) {
ComplexDspBuffer< std::complex<double> > buf(1);
return 0;
}
#包括“ComplexDspBuffer.h”
int main(int argc,字符**argv){
ComplexDspBufferbuf(1);
返回0;
}
在我看来,这不应该是一个构建问题,但是编译器(Xcode 5.0.2)会产生如下错误-“/Applications/Xcode.app/Contents/Developer/toolschains/Xcode default.xcodeToolschain/usr/lib/c++/v1/algorithm:644:97:二进制表达式的操作数无效('const std::u 1::complex'和'const std:u 1::complex')”
它是指std::sort使用的无模板函数。换句话说,它就是构建DspBuffer
操作符问题是没有操作符问题是没有操作符问题是没有操作符问题是没有操作符首先,您应该正确使用术语:重载意味着将一个函数名与不同的参数一起使用,而重写意味着在派生类中用更专门的版本替换虚拟函数,两者之间存在差异。据我所知,在所有使用重载的情况下,实际上都意味着重写
任何具体的虚拟函数都可以被调用,即使它被重写:您只需使用相应基类的名称限定函数调用,例如:
buf.DspBuffer<std::complex<double>>::sort();
buf.DspBuffer::sort();
将调用基类版本。此外,在对象的生命周期内,它实际上改变了它的类型:在类的构造函数和析构函数中,对象的类型是构造函数或析构函数的类,即使它最终成为更派生的类。为此,将实例化所有具体的虚拟函数
最简单的解决方法是专门化DspBuffer::sort()的实现,例如:
template <>
void DspBuffer<std::complex<double>>::sort() {
std::sort(buf.begin(), buf.end(),
[](std::complex<double> const& c0, std::complex<double> const& c1) {
return c0.real() < c1.real()
|| (!(c1.real() < c0.real()) && c0.imag() < c1.imag());
});
}
模板
void DspBuffer::sort(){
排序(buf.begin(),buf.end(),
[](标准::复常数和c0,标准::复常数和c1){
返回c0.real()
我不太喜欢函数只在被调用时才断言,特别是如果有可能提供一个完全可行的实现:仅仅因为小于运算符对数学公理没有意义并不意味着复数不能按顺序排序。首先,您应该正确使用术语:重载意味着将一个函数名与不同的参数一起使用,而重写意味着在派生类中用更专门的版本替换虚拟函数,两者之间存在差异。据我所知,在所有使用重载的情况下,实际上都意味着重写
任何具体的虚拟函数都可以被调用,即使它被重写:您只需使用相应基类的名称限定函数调用,例如:
buf.DspBuffer<std::complex<double>>::sort();
buf.DspBuffer::sort();
将调用基类版本。此外,在对象的生命周期内,它实际上改变了它的类型:在类的构造函数和析构函数中,对象的类型是构造函数或析构函数的类,即使它最终成为更派生的类。为此,将实例化所有具体的虚拟函数
最简单的解决方法是专门化DspBuffer::sort()的实现,例如:
template <>
void DspBuffer<std::complex<double>>::sort() {
std::sort(buf.begin(), buf.end(),
[](std::complex<double> const& c0, std::complex<double> const& c1) {
return c0.real() < c1.real()
|| (!(c1.real() < c0.real()) && c0.imag() < c1.imag());
});
}
模板
void DspBuffer::sort(){
排序(buf.begin(),buf.end(),
[](标准::复常数和c0,标准::复常数和c1){
返回c0.real()
我不太喜欢函数只在被调用时才断言,特别是如果有可能提供一个完全可行的实现:仅仅因为小于运算符对数学公理没有意义并不意味着复数不能按顺序排序。首先,您应该正确使用术语:重载意味着将一个函数名与不同的参数一起使用,而重写意味着在派生类中用更专门的版本替换虚拟函数,两者之间存在差异。据我所知,在所有使用重载的情况下,实际上都意味着重写
任何具体的虚拟函数都可以被调用,即使它被重写:您只需使用相应基类的名称限定函数调用,例如:
buf.DspBuffer<std::complex<double>>::sort();
buf.DspBuffer::sort();
将调用基类版本。此外,在对象的生命周期内,它实际上会更改其类型:在