我正在尝试为接口(interface)类编写一个适配器类,该接口(interface)类接受 a) 接口(interface)的实现,该实现应该是堆栈分配的(因此不需要从在外部,适配器本身可以使用 new/delete) 和 b) 将由接口(interface)的相应实现调用的 lambda 函数。
#include <iostream>
#include <functional>
struct interface {
virtual int hello() = 0;
};
struct implementation : public interface {
virtual int hello() {
std::cout << "hello()\n";
return 42;
}
};
struct adapter {
interface* obj;
adapter(std::function<int()>&& func) {
struct lambda : public interface {
std::function<int()> func;
lambda(std::function<int()> func_): func(func_) { }
virtual int hello() {
return this->func();
}
};
this->obj = new lambda{func};
}
adapter(interface&& impl) {
// TODO: pretty sure that's incorrect
// but can I somehow create a copy of "impl" on the heap?
this->obj = &impl;
}
};
int main() {
adapter a([]() { std::cout << "hello from lambda\n"; return 99; });
a.obj->hello();
#if 0
// ERROR
adapter b(implementation());
b.obj->hello();
#endif
return 0;
}
这是我在启用 adapter b
部分时遇到的错误。
prog.cpp: In function 'int main()':
prog.cpp:39:4: error: request for member 'obj' in 'b', which is of non-class type 'adapter(implementation (*)())'
b.obj->hello();
^
- 我根本不明白这个错误,非常感谢您的解释
- 如何才能真正正确地实现
adapter(interface&&)
构造函数?我可能需要在堆上创建对象的拷贝,否则在adapter
构造函数之后它不会持久化
在 ideone 上测试:http://ideone.com/Gz3ICk使用 C++14 (gcc-5.1)
PS:是的,adapter
类缺少一个析构函数,该析构函数应该删除从 lambda 构造函数创建的 obj
最佳答案
尝试使用
adapter b {implementation()};
问题在于
adapter b(implementation());
没有被解释为(如果我没记错的话)adapter
类型的对象的实例化但被解释为名称为 b
的函数的声明接收 采用单个(未命名)参数,该参数也是一个函数,返回类型实现并且不采用任何参数[Songyuanyao 更正] 并返回 implementation
类型的对象adapter
.
我知道有两种解决方案来解决这个歧义
1) 添加几个括号
adapter b((implementation()));
2) 使用基于大括号的新统一初始化样式
adapter b {implementation()};
我建议使用表格 2,因为您使用 C++11 并且(恕我直言)它更清晰。
--- 添加了解决生命周期问题的示例 ---
解决impl
的复制/克隆/生命周期问题,好吧...您正在使用指向纯虚拟基类的指针;我看到的唯一解决方案意味着克隆派生类。
我提出了一个解决方案
1) 已切换 obj
在adapter
来自interface *
至std::unique_ptr<interface>
(以避免释放问题)
2) 添加纯虚拟成员(member)clone()
在interfece
返回 std::unique_ptr<interface>
3) 添加了一个中间模板类 ( interHelper
) 来实现 clone()
只有一次
以下是我提出的解决方案
#include <memory>
#include <iostream>
#include <functional>
struct interface
{
virtual int hello() = 0;
virtual std::unique_ptr<interface> clone () const = 0;
};
template <typename D>
struct interHelper : public interface
{
std::unique_ptr<interface> clone() const override
{ return std::unique_ptr<interface>(new D((const D &)(*this))); }
};
struct implementation : public interHelper<implementation>
{
int hello() override
{
std::cout << "hello()\n";
return 42;
}
};
struct adapter
{
struct lambda : public interHelper<lambda>
{
std::function<int()> func;
lambda (std::function<int()> func_): func(func_)
{ }
int hello() override
{ return this->func(); }
};
std::unique_ptr<interface> obj;
adapter (std::function<int()>&& func) : obj { lambda{func}.clone() }
{ }
adapter (interface&& impl) : obj { impl.clone() }
{ }
};
int main()
{
adapter a([]() { std::cout << "hello from lambda\n"; return 99; });
a.obj->hello();
adapter b { implementation() };
b.obj->hello();
return 0;
}
附注:抱歉我的英语不好
关于c++ - 具有 move 构造函数的 C++ 接口(interface)适配器类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38038112/