#include <iostream>
using namespace std;
template <typename T>
class ISignalFilter;
template <typename F>
class ProductFilter;
template <typename T>
class ISignalFilter {
public:
virtual T filtered_value(const T& value) {
(void)value;
std::cout << "Base case usage of method not allowed";
std::abort();
};
virtual ProductFilter<T> operator*(ISignalFilter<T>& other) {
return ProductFilter<T>(*this, other);
}
};
template <typename F>
class ProductFilter : public ISignalFilter<F> {
public:
ProductFilter(ISignalFilter<F>& a, ISignalFilter<F>& b) {
a_ = &a;
b_ = &b;
}
F filtered_value(const F& value) override {
return b_->filtered_value(a_->filtered_value(value));
}
ISignalFilter<F>* a_;
ISignalFilter<F>* b_;
};
template <typename T>
class IdentityFilter : public ISignalFilter<T> {
public:
IdentityFilter() {}
T filtered_value(const T& value) override { return value; }
};
int main() {
std::cout << "hello world" << std::endl;
auto filter1 = IdentityFilter<double>();
auto filter2 = filter1 * filter1 * filter1;
while (true) {
double value;
std::cout << "input:";
std::cin >> value;
std::cout << "filtered: " << filter1.filtered_value(value) << std::endl;
std::cout << "filtered: " << filter2.filtered_value(value) << std::endl;
std::cout << "The two values above should be always equal."
<< std::endl;
}
}
基本上,我希望能够在
ISignalFilter
下创建子类,它们只需要实现 filtered_value
并且它们都应该自动与 *
运算符一起使用。
这段代码可以工作。它在
filter1 * filter1
下编译并可以工作,但是一旦我这样做 filter1 * filter1 * filter1
,我就会遇到段错误。
你的问题是你在
ISignalFilter<F>
中保留了指向ProductFilter<T>
的指针。但是像 filter1 * filter1
这样的操作会返回一个临时对象,该对象在表达式末尾被销毁。然后你的指针就失效了。
由于在这种情况下无法按值保存对象,因此可能需要使用智能指针,例如
std::shared_ptr<ISignalFilter<F>>
。或者,定义一个虚拟复制函数并在 ProductFilter<T>
中保留副本,而不是指向可能无效对象的指针。