【问题标题】:C++ Template constructor of a inherited class继承类的 C++ 模板构造函数
【发布时间】:2012-06-11 18:02:42
【问题描述】:

根据我对 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&’

我不知道这里发生了什么。有什么想法吗?

【问题讨论】:

标签: c++ templates inheritance constructor


【解决方案1】:

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

当传递A 类型的东西时,它无法弄清楚如何构造D

然后它会显示它所知道的两种构造函数选择:

test.cpp:44:7: note: D::D()
test.cpp:44:7: note: D::D(const D&)

它指出,对于每一个,它都有一个不能使用它的原因。对于第一个,它不需要任何参数。对于第二个,它无法将 A 类型的东西转换为 D 类型。

【讨论】:

  • 我同意您的解决方案可能有效,并且您的理由似乎很好,但我要补充一点,他的错误中的最后两行表明编译器可能试图在复制构造函数中“推断” D 也是,编译器可以自己生成。这个额外的错误也可能使 OP 感到困惑。
  • @Kevin:感谢反馈,我扩展了错误信息的解释。问候。
【解决方案2】:

根据我对 C++ 继承的理解,每当调用子类的构造函数时,都会自动调用父类的构造函数。

注意:父类的构造函数会自动调用,参数与子类的构造函数相同。

至于手头的具体问题:没有为类 D 声明构造函数。您将免费获得一个默认构造函数和复制构造函数,但不是 C 类中基于模板的构造函数。构造函数不是继承的。

【讨论】:

    猜你喜欢
    • 2019-12-14
    • 2013-09-04
    • 1970-01-01
    • 2013-05-21
    • 2016-03-04
    • 1970-01-01
    • 2016-12-30
    • 2017-10-20
    • 2019-12-14
    相关资源
    最近更新 更多