根据我对C ++继承的理解,无论何时调用子类的构造函数,都会自动调用父类的构造函数。对于模板化构造函数,模板参数的数据类型会自动输入,即我们不需要单独指定模板参数。该程序生成一个我似乎不理解的编译错误。
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
class A{
public:
int x;
int y;
int first(){
return x;
}
int second(){
return y;
}
};
class C{
public:
float a,b;
C(){
a = 0.0f;
b = 0.0f;
}
template<class T>
C(T t){
a = t.first();
b = t.second();
}
};
class D: public C{
public:
float area(){
return a*b;
}
}
int main(){
A a;
a.x = 6;
a.y = 8;
C c(a);
D d(a);
cout<<c.a<<" "<<c.b<<" "<<d.area()<<endl;
}
生成编译错误
test.cpp: In function ‘int main()’:
test.cpp:56:8: error: no matching function for call to ‘D::D(A&)’
test.cpp:56:8: note: candidates are:
test.cpp:44:7: note: D::D()
test.cpp:44:7: note: candidate expects 0 arguments, 1 provided
test.cpp:44:7: note: D::D(const D&)
test.cpp:44:7: note: no known conversion for argument 1 from ‘A’ to ‘const D&’
我不知道这里发生了什么。有什么想法吗?
答案 0 :(得分:5)
D
必须将构造函数参数传递给C
,因为您没有使用默认构造函数。
class D : public C {
public:
template <typename T> D (T t) : C(t) {}
float area () { /* ... */ }
};
错误的原因是您尝试使用参数构造D
,但尚未声明任何允许您这样做的构造函数。此外,您必须将参数传递给C
,否则编译器将使用C
的默认构造函数。
可以像这样分析编译器错误消息。
test.cpp:56:8: error: no matching function for call to ‘D::D(A&)’
编译器抱怨:
D d(a);
当传递D
类型的内容时,它无法弄清楚如何构建A
。
然后介绍它所知道的两种构造函数选择:
test.cpp:44:7: note: D::D()
test.cpp:44:7: note: D::D(const D&)
它指出,对于每一个,都有一个不能使用它的原因。对于第一个,它不需要任何参数。对于第二个,它无法将A
类型的内容转换为类型D
。
答案 1 :(得分:1)
根据我对C ++继承的理解,无论何时调用子类的构造函数,都会自动调用父类的构造函数。
小心:使用与子类的构造函数相同的参数自动调用父类的构造函数。
至于手头的具体问题:没有为类D声明构造函数。您将获得默认构造函数和复制构造函数作为freebies,但不是C类中基于模板的构造函数。构造函数不会被继承。