尝试在 C++ 中实现类似于类型类的东西,但出现段错误

问题描述 投票:0回答:1
#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
,我就会遇到段错误。

c++ haskell inheritance typeclass
1个回答
3
投票

你的问题是你在

ISignalFilter<F>
中保留了指向
ProductFilter<T>
的指针。但是像
filter1 * filter1
这样的操作会返回一个临时对象,该对象在表达式末尾被销毁。然后你的指针就失效了。

由于在这种情况下无法按值保存对象,因此可能需要使用智能指针,例如

std::shared_ptr<ISignalFilter<F>>
。或者,定义一个虚拟复制函数并在
ProductFilter<T>
中保留副本,而不是指向可能无效对象的指针。

© www.soinside.com 2019 - 2024. All rights reserved.