c++ - 具有 move 构造函数的 C++ 接口(interface)适配器类

标签 c++ c++11 interface move-semantics object-lifetime

我正在尝试为接口(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();
    ^
  1. 我根本不明白这个错误,非常感谢您的解释
  2. 如何才能真正正确地实现 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 的函数的声明接收 implementation 类型的对象 采用单个(未命名)参数,该参数也是一个函数,返回类型实现并且不采用任何参数[Songyuanyao 更正] 并返回 adapter .

我知道有两种解决方案来解决这个歧义

1) 添加几个括号

adapter b((implementation()));

2) 使用基于大括号的新统一初始化样式

adapter b {implementation()};

我建议使用表格 2,因为您使用 C++11 并且(恕我直言)它更清晰。

--- 添加了解决生命周期问题的示例 ---

解决impl的复制/克隆/生命周期问题,好吧...您正在使用指向纯虚拟基类的指针;我看到的唯一解决方案意味着克隆派生类。

我提出了一个解决方案

1) 已切换 objadapter来自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/

相关文章:

c++11 - 正则表达式匹配

c++ 重数据处理和分页

c++ - C++ 中对 const Callable 的引用和对 Callable 的引用之间的区别

c++ - 如何创建相互返回的 C++ 函数?

c - 如何为 C 游戏创建界面

css - (OOP 技术)继承与接口(interface) --- 相同的概念?---(CSS 技术)样式标签与样式类?

c++ - 在这种情况下使用 std::vector 的哪个构造函数

c++ - 如何读取子进程的返回码

c++ - c++11 中首选的初始化方式

java - 如何调用列表中某些对象实现的特定接口(interface)? java