11

如果是这样,为什么?为什么不使用值类型的复制构造函数?

我收到以下错误:

/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc: In member functio
n `ClassWithoutAss& ClassWithoutAss::operator=(const ClassWithoutAss&)':
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238:   instantiate
d from `void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterato
r<typename _Alloc::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp =
ClassWithoutAss, _Alloc = std::allocator<ClassWithoutAss>]'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_vector.h:564:   instantia
ted from `void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Class
WithoutAss, _Alloc = std::allocator<ClassWithoutAss>]'
main.cpp:13:   instantiated from here
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: error: non-st
atic const member `const int ClassWithoutAss::mem', can't use default assignment
 operator

在以下代码上运行 g++ main.cpp:

/*
 * ClassWithoutAss.h
 *
 */

#ifndef CLASSWITHOUTASS_H_
#define CLASSWITHOUTASS_H_

class ClassWithoutAss
{

public:
    const int mem;
    ClassWithoutAss(int mem):mem(mem){}
    ClassWithoutAss(const ClassWithoutAss& tobeCopied):mem(tobeCopied.mem){}
    ~ClassWithoutAss(){}

};

#endif /* CLASSWITHOUTASS_H_ */

/*
 * main.cpp
 *
 */

#include "ClassWithoutAss.h"
#include <vector>

int main()
{
    std::vector<ClassWithoutAss> vec;
    ClassWithoutAss classWithoutAss(1);
    (vec.push_back)(classWithoutAss);

    return 0;
}
4

2 回答 2

13

C++03 标准规定元素必须是可复制构造和可复制分配的,才能在标准容器中使用。因此,实现可以随意使用。

在 C++0x 中,这些要求是基于每个操作的。(一般来说,元素必须是可移动构造和可移动赋值的。)

为了得到你想要的,你应该使用一个智能指针shared_ptr(来自 Boost、TR1 或 C++0x),并完全禁用复制能力:

class ClassWithoutAss
{
public:
    const int mem;

    ClassWithoutAss(int mem):mem(mem){}
    // don't explicitly declare empty destructors

private:
    ClassWithoutAss(const ClassWithoutAss&); // not defined
    ClassWithoutAss& operator=(const ClassWithoutAss&); // not defined
};

typedef shared_ptr<ClassWithoutAss> ptr_type;

std::vector<ptr_type> vec;
vec.push_back(ptr_type(new ClassWithoutAss(1)));

指针可以很好地复制,智能指针可确保您不会泄漏。在 C++0x 中,您可以std::unique_ptr利用移动语义来做到这一点。(您实际上并不需要共享语义,但在 C++03 中它是最简单的。)

于 2010-07-17T18:27:17.887 回答
5

这里的问题是容器中的类型必须是可分配的。

因为您没有为您的类定义赋值运算符,所以编译器将为您生成一个。默认赋值运算符如下所示:

ClassWithoutAss& operator=(ClassWithoutAss const& rhs)
{
    mem = copy.mem;
    return *this;
}
// The compiler generated assignment operator will copy all members
// using that members assignment operator.

在大多数情况下,这会起作用。但是成员 mem 是一个常量,因此是不可分配的。因此,当它尝试生成赋值运算符时编译将失败。

于 2010-07-17T18:43:41.860 回答