2

struct A初期化されたさまざまなデータメンバーを持ついくつかのコンストラクターを持つ があります。

template<typename T>
    struct A {

    typedef std::vector<T> type1
    type1 a;
    type1 b;
    type1 c;

    A(type1 i_a): a(i_a) {
    }

    A(type1 i_a, type1 i_b): A(i_a), b(i_b) {
    }

    A(type1 i_a, type1 i_b, type1 i_c): A(i_a, i_b), c(i_c) {
    }
};

私が取得custom_typeするエラーは、 say でインスタンス化したときに発生します。エラーは、 type A<custom_type> is not direct base of A<custom_type>別のコンストラクター内で呼び出すコンストラクターを強調表示しています。C++11 を使用しています。どうしたの?

4

3 に答える 3

7

コンストラクターは、その基本クラスとメンバーを初期化するか、または同じクラスの別のコンストラクターに委任することができますが、両方を行うことはできません。

A(i_a)完全なオブジェクトを構築し、メンバーとデフォルト構築およびをAコピーします。したがって、最初のイニシャライザはすでに初期化されています。代わりにabcA(type1 i_a, type1 i_b): A(i_a), b(i_b) {}b

A(type1 i_a, type1 i_b) : A(i_a) { b = std::move(i_b); }
于 2013-03-15T17:43:06.453 に答える
1

ascheplerが答えを提供しますが、問題の原因を説明し、それを回避するためにコンストラクターを委任するための「ベストプラクティス」を示したいと思いました。

コードには一連のコンストラクターがあり、それぞれが委任先のコンストラクターよりも一般的です。つまり、すべてを実行するわけではない、より特殊なコンストラクターにコンストラクターを委任しようとしているので、余分な一般性を処理するために少し作業を行います。これは、それをサポートする以前の言語での建設委任の最も実用的な方法であることが判明したものとは逆です。

代わりに必要なのは、最も一般的なコンストラクターを委任の「ルート」(他の言語では「指定された初期化子」または「指定されたコンストラクター」)にすることです。より特殊なコンストラクターは、より一般的なコンストラクターを使用して作業を行い、処理される特殊なケースのデータを渡します。

あなたの場合、特殊な動作は、ユーザーから初期値を取得する代わりに、一部のメンバーにデフォルト値を使用することです。したがって、より専門的なコンストラクターは、他のメンバーのデフォルト値とともに、指定されたパラメーターを渡すことによって作業を行います。

template<typename T>
struct A
{
    typedef std::vector<T> type1;
    type1 a;
    type1 b;
    type1 c;

    A(type1 i_a, type1 i_b, type1 i_c): a(i_a), b(i_b), c(i_c) {}

    A(type1 i_a, type1 i_b): A(i_a, i_b, {}) {}

    A(type1 i_a): A(i_a, {}) {}
};
于 2013-03-15T18:38:05.967 に答える
0

ただし、コンストラクターの本体から同じクラスの異なるコンストラクターを呼び出すことはできます(何らかの理由で必要な場合)

class CComplex{
public:
    CComplex(int real1,int image1,char c)
    {
        cout<<"RealImg";
        real=real1;
        image=image1;
        char* x; char xc=c;x=&xc;
        void* v;
        f(x);
        CComplex ccc(x,v); //this is OK
        CComplex cccc(1,2,3); //as this too
    }
    CComplex():real(0),image(0){cout<<"DEFAULT";}
    CComplex(const CComplex &c)
    {
        real=c.real;
        image=c.image;
        cout<<"COPY";
    }
    CComplex& operator=(CComplex const& ref){ 
        cout<<"ASSIGN";
        //CComplex* c;
        CComplex cobj(43,45,'x');
        //c=&cobj;
        //CComplex* c=new CComplex(44,45); 
        return cobj;
    }

    CComplex(int i1, int i2, int i3){cout<<"\n123!";}
    CComplex(const char* y,void* v){cout<<"\nCrefvoid!";}
    ~CComplex(){cout<<"\n~CComplex(){}";}
public:
    void Display(void)
    {
        cout<<real<<"+"<<image<<"i"<<endl;
    }
    static bool CComplexComparator(CComplex c1, CComplex c2){return true;}
    static void CComplexInit(CComplex& c){
        c.real=100;
    }
    int real,image;
}; 
于 2013-03-15T18:12:04.087 に答える