在c++中从另一个构造函数调用构造函数时出错

Error while calling constructor from another constructor in C++

本文关键字:函数调用 构造函数 出错 c++ 另一个      更新时间:2023-10-16

我有一个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。有什么问题吗?

构造函数可以初始化其基类和成员,或者委托给同一类的另一个构造函数,但不能同时初始化。

A(i_a)复制成员a,并默认构造bc,构造了一个完整的A对象。所以使用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); }

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, {}) {}
};

但是您仍然可以从构造函数的主体调用同一类的不同构造函数(如果出于某种原因您想要)

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