从C ++中的另一个构造函数调用构造函数时出错

时间:2013-03-15 17:38:06

标签: c++ c++11 constructor ctor-initializer

我有一个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实例化它时,错误是 type A<custom_type> is not direct base of A<custom_type>突出显示我在另一个构造函数中调用的构造函数。我正在使用C ++ 11。有什么问题?

3 个答案:

答案 0 :(得分:7)

构造函数可以初始化它的基类和成员,或者委托给同一个类的另一个构造函数,而不是两者。

A(i_a)构建一个完整的A对象,复制成员a和默认构建bc。因此,A(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); }

答案 1 :(得分: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, {}) {}
};

答案 2 :(得分: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;
};