gpt4 book ai didi

c++ - 使用指向类 T 成员的函数指针作为模板类 函数中的参数的不良做法?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:31:04 26 4
gpt4 key购买 nike

首先,对标题感到抱歉。我真的无法将我想问的内容浓缩成一个短语:(

我正在阅读 this post ,它不知何故让我开始思考函数指针。具体来说,我想知道为什么将类成员函数作为函数参数传递然后在该函数内的现有对象上使用该指针是“不好的”(或者至少很少见到)。

假设我有一个模板类“Container”,它存储一个类型为 T 的变量,并提供一个方法来获取对该变量的 const 引用。

template<class T>
class Container {
public:
Container(T anObject) {
m_data = anObject;
}
const T& getData() const {
return m_data;
}
private:
T m_data;
};

现在,我希望能够在 m_data 上执行 T 的成员函数,但我不想使 getData() 成为非 const,因为这会导致返回的引用发生各种其他恶作剧。我的解决办法是给Container增加一个新的public函数modifyData(...),它以一个指向T的成员函数的函数指针为参数,在m_data上执行;像这样:

// ...
void modifyData( void(typename T::*funcptr)(void) ) {
(m_data.*fptr)();
}
// ...

照原样,如果 T 是指针,这将崩溃并烧毁。为了测试,我刚刚为 Container<T*> 创建了一个专门的模板来解决这个问题,但我相信会有更优雅的方法。

一个经过深思熟虑的示例表明这似乎按预期工作:

// example class to be used with Container
class Data {
public:
Data() {m_count = 0; }
void incrementCount() { m_count++; }
int getCount() const { return m_count; }
private:
int m_count;
};

// ... in main.cpp:
Data dat;
Container<Data*> DCont(dat);
std::cout << cl.getData()->getCount() << std::endl; // outputs 0
DCont.modifyData<Data>(&Data::incrementCount);
std::cout << cl.getData()->getCount() << std::endl; // outputs 1

// compiler catches this:
// DCont.modifyData<SomeOtherClass>(&Data::incrementCount);
// this probably does something bad:
// DCont.modifyData<SomeOtherClass>(&SomeOtherClass::someFunc);

现在,直觉上这似乎是一种非常扭曲的做事方式,而且我从未见过这样工作的代码。但我的问题是,是否有性能/安全原因导致这样的事情不好,或者它只是被认为是不好的做法?如果这“只是”不好的做法,那是为什么呢?

我能想到的明显限制是 //DCont.modifyData(&SomeOtherClass::someFunc);可能会在运行时崩溃,但我认为这可以通过在 incrementData() 中检查 U 与 T 的类型来解决。此外,实际上,modifyData 仅接受 void (*)() 函数,但这可能可以通过可变模板来解决。

这个例子显然解释得很清楚,但实现得不是很好,但我认为(希望?)它足以解释我在说什么。

谢谢!

编辑: 关于问题是什么,似乎有些混淆。基本上,这就是我正在谈论的场景:你有一堆来自某个库的类,你试图将它们存储在容器中,以及另一个生成特定容器的函数;现在,您希望用户能够在这些容器中的对象上调用现有的成员函数,但不能修改实际的对象(比如使用 getter 返回非常量引用时)。实际的实现可能会使用某种有用的可变参数模板,但在发布示例代码之前我需要考虑更多。

简而言之,我想限制用户对容器成员的访问仅限于该成员的成员函数。有没有更简单的方法来做到这一点,或者这种方法不符合我的预期?

最佳答案

我对您的架构没有任何问题 - 我不认为这是不好的做法。对我来说,这似乎是一种保护数据的费力方法,并且对您没有多大帮助,因为用户可以使用任何 void 函数来修改包含的数据,而这实际上不是关于可以更改和不能更改的内容的契约(Contract)。

我认为这种构造很少见的原因是您对容器类的要求和目标不寻常。

关于c++ - 使用指向类 T 成员的函数指针作为模板类 <T> 函数中的参数的不良做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11955476/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com