有没有一种方法可以在C++中将方法存储在某种类型的向量中?

4

这是我第一次来到这里。

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

我的想法是添加类似于posterize()rgbSplit()等方法。 当它们被初始化时,它不会为每个效果遍历所有像素,因为那样的性能不佳。 我希望它在稍后使用名为process()的方法时存储应处理这些效果的事实。

但是,我需要将效果代码的引用存储在列表(如向量)中吗? 因为然后我可以进入x和y坐标的for循环,并添加另一个for循环,以遍历应用于像素的所有方法。

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


是的。请展示你的代码。用英语描述的代码极难理解。 - 463035818_is_not_a_number
2
这回答解决了你的问题吗?如何将函数存储到变量中? - Asteroids With Wings
@idclev463035818 这里不需要代码,问题已经很清楚了。 - Asteroids With Wings
你可以用一个类来封装向量,为该类添加方法,并通过调用类方法来操作向量。 - bowman han
好的,我想我得学习如何使用所谓的“函数指针”,对吗?我刚试了一些东西,但是它给了我一些错误,不过我想在向您提问之前尝试不同的方法。非常感谢您迄今为止的帮助! - Florian Mrugalla
4个回答

5
这个问题非常宽泛。但我理解你是初学者,需要知道是否有可能,在编写代码之前了解一些情况。
因此,这里是一个快速的低级答案:
  • 是的,您可以拥有函数指针的向量;
  • 是的,您可以拥有std::function的向量,它比原始函数指针更强大和灵活;
  • 是的,您可以通过将其作为虚函数放置在类中并像使用函数一样使用它来“对象化”方法(使用方法名称并实现命令模式,或者使用operator()来实现经典的函数对象)。
  • 是的,您甚至可以通过用责任链模式的变体替换数组来以更灵活的方式链接不同的光栅操作。

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

  • 一些图像滤镜可以在像素级别上工作,那么你的方法是正确的。
  • 但有些图像滤镜会在一组相邻像素上工作。如果你按像素处理,链接将无法正常工作,因为已经处理过的像素和仍未处理的原始像素在处理的组中混杂在一起。

因此,你的设计需要应对这两种算法。例如,你可以先对所有像素应用初步的像素转换,然后只在已经转换过的像素组上运行算法,然后继续进行链式操作。

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

一旦你考虑清楚了这些问题,并开始实现上述其中一种想法的解决方案,你可以带着更精确的问题和一些代码回到这里。


1
此外,即使您想循环遍历所有像素并对每个像素执行X、Y、Z操作,一次循环遍历所有像素并执行X、Y和Z操作并不比分别循环遍历像素三次在性能上更有优势。 - Daniel McLaury
@DanielMcLaury 这确实是一个非常相关的评论!我们不是一次性处理数百万像素,而是处理一个像素就要进行数百万次调用。非常感谢您指出这一点!我已经相应地进行了编辑(当然带有归属)。 - Christophe
关于设计方面的好点子,你说得很对。我之前也有同样的想法。我的想法是,当图像被引用到处理函数中时,该函数会创建一个新的图像,并将所有处理过程从引用的图像传递到新图像。当所有循环结束后,我通过“image = newImage”来将其带回实际的图像。这就是为什么我认为我的实现目前还不错。但是,正如你正确指出的那样,我是个初学者,所以我做的一切都可能是错误的。 - Florian Mrugalla
@FlorianMrugalla 没问题。实验是最好的老师! - Christophe

0

0

我目前正在跟随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:

};

它在一些函数下面划了下划线,错误提示如下:

类型为“void (ImagePP::)()”的值无法用于初始化类型为“void()()”的实体


如果我理解正确的话,它说我不能这样做,因为我不是在主函数中,而是在一个类中。但那我该怎么办呢?我想在这个类中使用它。


实例成员函数与静态函数不同。作为新手,您可以从std :: function和lambda开始。 - Red.Wave

0
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时,我也有同样的错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接