【问题标题】:Is there a way to store methods in some type of vector in c++?有没有办法在 C++ 中将方法存储在某种类型的向量中?
【发布时间】:2020-03-01 17:16:52
【问题描述】:

这是我第一次来这里。

我目前正在尝试通过遍历所有像素并对那里的颜色进行处理来编写一个用于后处理图像的类。

我的想法是添加posterize()rgbSplit() 等方法。当它们被初始化时,它不会遍历每个效果的所有像素,因为这不是很高效。我希望它在稍后使用名为process() 的方法时存储它应该在给定链中处理这些效果的事实。

但因此我必须将效果代码的引用存储在一个列表中(如矢量),对吧?因为那时我可以进入 x 和 y 坐标的for 循环,并在那里添加另一个 for 循环,该循环遍历所有应该应用于像素的方法。

问题是,我不知道如何将方法存储在向量中。这甚至可能吗?还是向量仅适用于对象?或者我可以以某种方式“客观化”一种方法吗?或者我现在必须做什么?

【问题讨论】:

  • 是的。请出示您的代码。用英文描述的代码非常难以理解
  • 这能回答你的问题吗? How do I store a function to a variable?
  • @idclev463035818 这里不需要代码问题很清楚
  • 可以用类包装向量,给类添加方法,调用类方法对向量进行操作
  • 好吧,我想我必须学习如何使用所谓的“函数指针”,对吗?我只是尝试了一些东西,它给了我错误,但我想在问你更多问题之前,我会继续尝试不同的东西。感谢您迄今为止的帮助!

标签: c++ image vector chaining juce


【解决方案1】:

这个问题非常广泛。但我知道你是在开始,在编写一些代码之前需要知道它是否可能。

所以这里是一个快速的低级答案:

  • 是的,您可以拥有function pointers 的向量;
  • 是的,您可以拥有std::function 的向量,它比原始函数指针更强大、更灵活;
  • 是的,您可以“对象化”一个方法,方法是将其作为虚函数放入类中,并像使用函数一样使用它(使用方法名称并实现 command pattern,或使用 operator() 来实现经典functor)。
  • 是的,您甚至可以通过将数组替换为chain of responsibility pattern 的变体,以更灵活的方式链接您的不同栅格操作

但在更高的层次上,你需要更好地思考你的设计:

  • 某些图像过滤器可以在像素级别上工作,然后您的方法就可以了
  • 但某些图像过滤器对一组相邻像素起作用。如果您逐个像素地工作,则链接将无法正常工作,因为在处理的组中将有已转换的像素和原始未转换的像素。

因此,您的设计需要同时处理这两种算法。例如,您可以首先将链中的初步像素变换应用于所有像素,然后仅对已变换的像素组运行算法,然后继续在链中。

此外,正如Daniel McLaury 在 cmets 中指出的那样,另一个问题是从性能的角度来看,逐像素调用算法是否有意义。也许链接算法是一个好主意,但在图像转换级别而不是像素级别。

一旦您考虑了这一点,并开始使用上述想法之一实施解决方案,您可能会带着更精确的问题回到这里,并用一些代码进行说明。

【讨论】:

  • 此外,即使您想遍历所有像素并对每个像素执行 X、Y、Z而不是循环遍历像素三次。
  • @DanielMcLaury 这确实是一个非常相关的评论!与处理一百万个像素的调用不同,我们有处理一个像素的一百万个调用。非常感谢您指出!我已经进行了相应的编辑(当然有署名)
  • 关于设计的好点子。我已经有了同样的想法。我对此的想法是,当图像被引用到处理函数时,然后在这个函数中创建一个新图像,并且所有处理都从引用的图像到新图像。当所有循环结束时,我会执行 image = newImage 以将其恢复为实际图像。这就是为什么我认为到目前为止我的实施还可以。但是,是的,正如你所说的,我是初学者。所以我所做的一切都可能是错误的
  • @FlorianMrugalla 没问题。实验是最好的老师!
【解决方案2】:

如果要使用观察者模式,那么 boost::signals2 是一个不错的候选者。

观察者模式 https://en.wikipedia.org/wiki/Observer_pattern?wprov=sfla1

升压::信号2 https://www.boost.org/doc/libs/1_72_0/doc/html/signals2.html

干杯, 调频。

【讨论】:

    【解决方案3】:

    我目前正在关注关于函数指针的 cherno 教程,因为我想也许我需要有人详细了解它并且结构非常好。 https://www.youtube.com/watch?v=p4sDgQ-jao4&t=306s

    在 5 分钟时,他通过说 void(*cherno)() = HelloWorld; 生成了一个函数指针

    我也尝试这样做,但出现错误。这是我的代码:

    class ImagePP {
    public:
        ImagePP() { }
    
        void someFunc() { DBG("someFunc started"); }
    
        void process() {
            DBG("process Started.");
    
            void(*function)() = someFunc;
            function;
        }
    private:
    
    };
    

    它强调了 someFunc 并且错误说:

    “void (ImagePP::)()”类型的值不能用于初始化“void()()”类型的实体


    如果我理解正确,它会说我不能这样做,因为我不是在 main 中做,而是在课堂上做。但那我该怎么办呢?我想在这个类中使用它

    【讨论】:

    • 实例成员函数不同于静态函数。作为一个新手,你从 std:: 函数和 lambda 开始。
    【解决方案4】:
    class ImagePP {
    public:
        std::function<void> someFunc(int i) { DBG("someFunc started: " << i); }
    
        void process() {
            DBG("process Started.");
    
            typedef std::function<void>(ImagePP::*FuncPtr)(int);
            FuncPtr function = someFunc;
            function(5);
        }
    };
    

    这就是我现在得到的。意识到它需要那里的类名,但现在它在 (5) 下划线,即使函数需要一个整数。它说:

    明显调用括号前的表达式必须具有(指向)函数类型

    当我使用普通 void 而不是 std::function 时,我遇到了同样的错误

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 2022-01-10
      • 2020-05-03
      • 2021-04-27
      • 1970-01-01
      相关资源
      最近更新 更多