简体   繁体   中英

parameterized constructor for inherited class templates

I have multiple inherited class, bur getting error C2<int (__cdecl *)(int)>': no appropriate default constructor available , but I defined parameterized constructor for C1,C2 .

A related question is I have seen commented line marked ??? in some code. What does it mean - it is initializing default constructor for C2 from C3 ?

#include <iostream>
int y(int) 
{ int a=1; return a } 

template<typename F>
class C1
{
public:
    F f1;
    C1(F g) : f1(g) {}  
};

template<typename F>
class C2 : public C1<F>
{
public:
    F f2;
    C2(F g) : f2(g) {}  
};

template<typename F>
class C3 : public C2<F>
{
public:
    F f3;
    C3(F g) : f3(g) {}
    //C3 (F g) : C2<F>(g) {}        ???
};


int main()
{
    C1 o1(y);
    C2 o2(y);
    C3 o3(y);
}

When you construct a class that is child to another class, the parent's default constructor (unless another one is explicitly called like in line marked ??? ) is invoked. But seeing as you provided a constructor for each class, the compiler did not generate an implicit default constructor. So when you create an instance of C2 , and the compiler tries to call the missing default constructor of C1 , it can't find it.

If you do provide a default constructor, this works:

#include <iostream>
int y(int) {
    int a=1;
    return a;
} 

template<typename F>
class C1 {
public:
    F f1{};

    C1() = default;

    C1(F g)
        : f1(g)
    { }  
};

template<typename F>
class C2 : public C1<F>
{
public:
    F f2{};

    C2() = default;

    C2(F g) 
        : f2(g)
    { }  
};

template<typename F>
class C3 : public C2<F>
{
public:
    F f3{};

    C3() = default;

    C3(F g) 
        : f3(g) 
    { }
    //C3 (F g) : C2<F>(g) {}        ???
};


int main()
{
    C1 o1(y);
    C2 o2(y);
    C3 o3(y);
}

The line marked ??? calls a specific parent constructor instead of relying on the implicit call to the parent class' default constructor.

So you can either provide default constructors like above, or you can adopt the ??? line syntax to call a specific constructor -- this depends on your class design and intentions.

As Sam says, C2 s constructor is trying to call the default constructor for C1 , which doesn't exist. Likewise, C3 is trying to call C2 s default constructor.

There are two fixes:

  • define default constructors for C1 and C2 , or:

  • modify C2 s constructor to call a constructor that does exist, like so:

    C2(F g) : C1 <F> (g), f2(g) {}

  • and similarly C3 s constructor, like so:

    C3(F g) : C2 <F> (g), f3(g) {}

Which, in itself, answers your second question, I think.

C2<F>(g) initializes the base class by calling its constructor. If you don't call a constructor yourself then the compiler will attempt to call default constructor for the base class ( C2<F>::C2() ) instead. None of your classes have default constructors which is the source of the error. But really what you should be doing is calling the base class constructors yourself.

C2(F g) : C1<F>(g), f2(g) {}
C3(F g) : C2<F>(g), f3(g) {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM