2012-02-15 100 views
0

这是内存映射文件共享的示例代码。 mapped_region是负责它的d类 现在我深入挖掘之前,我不能跟踪为什么使用这种声明。任何人都可以向我解释这个吗?是否有可能有一个构造函数的参数作为类名C++?

class mapped_region 
{ 
    // Non-copyable 
    mapped_region(const mapped_region &); 

    // Non-assignable 
    mapped_region &operator=(const mapped_region &); 

    public: 

    typedef /*implementation-defined*/ offset_t; 
    typedef /*implementation-defined*/ accessmode_t; 
    static const accessmode_t   invalid_mode; 
    static const accessmode_t   read_only; 
    static const accessmode_t   read_write; 
    static const accessmode_t   copy_on_write; 

    mapped_region(); 

    mapped_region(const memory_mappable & mappable 
       , accessmode_t   mode 
       , offset_t    mappable_offset 
       , std::size_t    size = 0 
       , const void *   address = 0); 

    mapped_region(mapped_region &&other); 

    std::size_t get_size() const; 

    void*  get_address() const; 

    offset_t get_offset() const; 

    accessmode_t get_mode() const; 

    void flush(std::size_t region_offset = 0, std::size_t numbytes = 0); 

    void swap(mapped_region &other); 

    ~mapped_region(); 
}; 

在这个例子中

// Non-copyable 
mapped_region(const mapped_region &); 

是什么意思呢?

回答

3

是的,可以有一个参数名称与class相同的构造函数。
两种情况是可能的:

在您的代码:

mapped_region(const mapped_region &); 

代表一个拷贝构造函数,而:

mapped_region(mapped_region &&other); 

代表移动构造函数

拷贝构造函数用于创建类对象的副本。无论何时您通过值传递类对象作为函数参数或者需要您的类对象的副本,编译器都会调用复制构造函数来创建此对象。

如果你想从使你的类对象的拷贝限制类的用户,那么你声明复印功能拷贝构造函数 & 拷贝赋值运算符=)作为private,这就是你的代码在这种情况下,它会限制您的代码的用户创建您的类mapped_region的任何副本。请注意,一个类的默认访问说明符是private

因为你的代码声明了一个移动的构造,我假设你正在使用C++ 11,从而更好的方式在这里实现所期望的功能是使用explicitly deleting special member functions在C++ 11提供。

对于如:

class mapped_region{ 
    mapped_region & operator=(const mapped_region&) = delete; 
    mapped_region(const mapped_region&) = delete; 
    mapped_region() = default; 
}; 
+0

非常感谢你,我现在可以更好地理解:) – Nisha 2012-02-15 11:41:09

+0

@judithnisha:没问题。很高兴能帮助你更好地理解:) – 2012-02-15 11:42:21

2

这是一个copy-constructor。它用于创建一个类的实例的副本。

mapped_region foo; 
mapped_region bar(foo); // creates bar as copy of foo 

如果声明的拷贝构造函数是私有的,那么在编译器错误的第二行的结果,因为它试图访问拷贝cosntructor。这样做是为了防止复制该类的对象。这通常在类包装无法复制的资源(如文件或线程)时完成。

+0

是的,它说“不可复制”,因为拷贝构造函数在这种情况下是私有的。 – 2012-02-15 10:55:38

+0

@LuchianGrigore:好的,做得更具体。 – 2012-02-15 10:57:17

+0

哦:)我现在明白了。 – 2012-02-15 10:58:31

2

class成员private默认。

class mapped_region 
{ 
    // Non-copyable 
    mapped_region(const mapped_region &); 

    // Non-assignable 
    mapped_region &operator=(const mapped_region &); 
public: 

    //... 
}; 

表示您声明了复制构造函数和赋值运算符private。这意味着你不能相互拷贝类的对象。

1
mapped_region(const mapped_region &); 

是复制构造函数的声明。

有时你不希望你的课是可复制的(所以你可以通过复制另一个来创建一个对象)。默认情况下,编译器会创建复制构造函数并启用复制。为了防止编译器创建此构造函数,您需要将其声明为私有,并省略其定义(实现)。试图创建一个对象的副本会在这种情况下会失败:

mapped_region mr1; 
mapped_region mr2(m1); // trying to call copy constructor call - error 

mapped_region mr1; 
mapped_region mr2 = m1; // trying to call copy constructor call - error 

注释:

// Non-copyable 

应用于拷贝构造函数的私有声明表明,它的目的仅仅是为了防止编译器创建一个默认的。 operator=也是如此。如果两个成员都是私有的,则不能将一个对象复制或分配给另一个对象。

0

请注意,当您在该类的专用部分中定义一个复制构造函数时,则不会给它一个实现。

如果您尝试复制该课程,您将得到一个链接错误。所以

void mapped_region::f() 
{ 
    mapped_region other(*this); // will compile because I have access to private functions 
} 

但代码将不会链接,因为它无法找到复制构造函数定义。 (请注意,如果你这样做,可能很难找到你正在复制的地方)。

禁止复制的另一种方法是从升压::不可复制派生类,即:

class mapped_region : boost::noncopyable 
{ 
    //etc. 

}; 

这样可以防止拷贝赋值太(运算符=)。几乎总是当你禁止复制时,你也禁止复制分配。