C ++ Wrapper类的含义是什么?

时间:2011-03-15 03:21:31

标签: c++ class wrapper

我在理解包装类时有点麻烦。如果有人可以帮助提供适当的例子,那将是很好的。

  1. 什么是C ++ Wrapper类?编写它的具体情况是什么?
  2. 有什么用途?
  3. 感谢。

5 个答案:

答案 0 :(得分:31)

“包装类”是一个事实上的术语,意思是“包裹”资源的类;即,管理资源。当人们写一个包装器时,他们正在做这样的事情:

class int_ptr_wrapper
{
public:
    int_ptr_wrapper(int value = 0) :
    mInt(new int(value))
    {}

    // note! needs copy-constructor and copy-assignment operator!

    ~int_ptr_wrapper()
    {
        delete mInt;
    }

private:
    int* mInt;
};

此类管理(“包装”)指向int的指针。所有资源都应该以某种方式包装,以保持清洁(没有明确的清理代码或噪音)和正确性(析构函数保证运行;不能忘记清理,并且安全例外)。

这种模式称为范围绑定资源管理(SBRM),但更常见(但最神秘)的名称是资源获取是初始化(RAII)。我们的想法是将资源的清理绑定到析构函数,原因如上所示:范围处理其余部分。

请注意,我说它缺少复制构造函数和复制赋值运算符。这是由Rule of Three引起的。 (有关详细说明,请参阅链接的问题。)正确实现此规则的最简单方法是使用复制和交换习惯用法,here解释。


有时,为资源清理编写包装类并不务实,通常在资源是唯一的或使用一次时。 (或使用事务编程。)解决方案称为范围保护,这是一种在需要它的函数内编写清理代码的方法。

您可以在自己喜欢的搜索提供商(即Google)中搜索更多信息,或者转到“主要”文档here。请注意,Boost为此提供a utility,因为它通常用于好习语。

答案 1 :(得分:10)

包装器只是一个小类,其目的是提供与它包装的东西不同的接口。例如,通常采用C API并编写一个或多个“包装”它的类来提供面向对象的接口而不是程序接口。

答案 2 :(得分:7)

您询问了编写包装类的情况。例如,如果您所在的公司使用不同类型的相机,请告诉我们USB,firewire等。每个制造商都将提供不同的功能集用于启动摄像头,设置参数并从中读取图像流的API。

现在,在公司中构建应用程序的程序员需要与各种API中的所有特定细节隔离开来。现在,你可以做的是围绕每个摄像头或更聪明的API编写一个包装类,只需一个具有简单功能的类,包围API提供的现有代码。

例如,我们可以设计类 MyUSBCameraWrapperClass, MyFirewireCameraWrapperClass 有一些成员函数,如 setFrameRate(int fps), getImgFrame(* framebuffer)等

贵公司的程序员可以使用MyUSBCameraWrapperClass usbcam; usbcam.setFrameRate(30)等你明白了吗?

答案 3 :(得分:3)

包装类是一个用另一个接口包装功能的类。

假设你有f()函数:

void f() { std::cout << "hello\n"; }

一个简单的包装类可能是

class C {
    f() { std::cout << "hello\n"; }
};

当您的现有代码库需要特定接口时,您可以编写包装器。这是适配器设计模式的本质。或者,如果您希望维护该函数的状态,则可以将函数包装在类中。或者,您可以将一个函数包装在类的构造函数或析构函数中,如果您希望以正确和确定的方式方便地自动调用它。名单还在继续。

答案 4 :(得分:2)

我使用两种:

  1. 操作系统提供的功能对的资源包装器,如

    • UNIXs:open / close,mmap / munmap,dlopen / dlclose
    • Windows:CreateFile / DestroyHandle,CreateFileMapping / CloseHandle,LoadLibrary / FreeLibrary
  2. 操作系统提供的功能的功能包装,如

    • UNIXs:write,read,dlsym
    • Windows:ReadFile,WriteFile,GetProcAddress
  3. 资源包装器确定,编译器生成的代码担心构造函数通过今天所谓的RAII创建的资源的破坏。通过基类/成员类关系将这些类组合成复杂的类很容易。 如果创建函数失败,则抛出系统错误异常,提供有关错误的丰富错误信息。

    使用功能包装器代替普通OS功能。如果发生故障,也会抛出系统异常。

    这样,使用我的代码的人不需要调试器和调试代码来找出在具有许多库和进程以及远程机器的复杂环境中失败的原因。

    这些包装器也提供了一些操作系统抽象 - 使用它们的代码不必担心操作系统的差异。