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)));

ポインターは問題なくコピーでき、スマート ポインターによってリークが防止されます。std::unique_ptrC++0x では、move-semantics を利用して、これを最もうまく行うことができます。(実際には共有セマンティクスは必要ありませんが、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 は const であるため、代入できません。したがって、代入演算子を生成しようとするとコンパイルが失敗します。

于 2010-07-17T18:43:41.860 に答える