【问题标题】:How to call a template super class's constructor from a template base class's constructor in c++?如何在 C++ 中从模板基类的构造函数调用模板超类的构造函数?
【发布时间】:2017-09-12 10:55:22
【问题描述】:

我正在使用 sublimetext3 在 c++ 中编程。我的程序有一个名为 Array 的超类和一个名为 IntArray 的子类。这两个类都是模板类。目前,我在编译程序时遇到了麻烦。它一直在我的 IntArray.cpp 文件中给我一个错误,特别是在我的基类的构造函数中,我用基类的构造函数的参数调用和初始化超类的构造函数。我不确定如何从子类的模板构造函数中调用超类的模板构造函数。错误消息如下所示。此外,错误消息下方是我的 main.cpp、Array.cpp、Array.h、IntArray.cpp、IntArray.h 和 Makefile 的源代码文件。该计划尚未完成。我目前只有一种获取数组大小的方法。

来自终端的错误消息:

IntArray.cpp:4:56: error: member initializer 'Array' does not name a non-static data member or base class
template<class T> IntArray<T>::IntArray(T s) throw() : Array(s) {
                                                       ^~~~~~~~

1 error generated.

ma​​in.cpp

#include <iostream>
#include <string>
#include "Array.h"
#include "IntArray.h"

int main(int argc, char** argv) {

  // make an array of doubles with size 10
  Array<int> iA(10);

  // get the size of the array
  std::cout<< "The size of IntArray is" <<iA.getSize()<<std::endl;

} // end of main

Array.cpp

#include "Array.h"

// constructor
template<class T> Array<T>::Array(T s) throw() {
  size = s;
}

// destructor
template<class T> Array<T>::~Array() throw() {

}

// getter methods
template<class T> T Array<T>::getSize() const throw() {
  return size;
}

Array.h

#ifndef ARRAY_H
#define ARRAY_H

template<class T> class Array {
private:
  T size;

public:
  Array(T s) throw();
  virtual ~Array() throw();
  // getter methods that throws an exception if the index is out of bounds
  T getSize() const throw();


  // setters that throws an exception if the index is out of bounds
};

#endif

IntArray.cpp

#include "IntArray.h"

// constructor
template<class T> IntArray<T>::IntArray(T s) throw() : Array(s) {

}

// desctructor
template<class T> IntArray<T>::~IntArray() throw() {

}

IntArray.h

#ifndef INTARRAY_H
#define INTARRAY_H
#include "Array.h"

template<class T> class IntArray : public Array<T> {

public:
  IntArray(T s) throw();
  virtual ~IntArray() throw();
  //int getSize() const throw();
};

#endif

生成文件

all:main

main.o: main.cpp Array.h IntArray.h
  g++ -c -Werror main.cpp

Array.o: Array.cpp Array.h
  g++ -c -Werror Array.cpp

IntArray.o: IntArray.cpp IntArray.h
  g++ -c -Werror IntArray.cpp

main: main.o Array.o IntArray.o
  g++ -o main main.o Array.o IntArray.o

【问题讨论】:

标签: c++ arrays templates inheritance


【解决方案1】:

使用

template <class T> IntArray<T>::IntArray(T s) throw() : Array<T>(s) {}
                                                        //   ^^^ Use <T>

更重要的是,将实现也放在 .h 文件中。

Why can templates only be implemented in the header file?

我注意到的其他问题

  • 您使用T s 作为大小是没有意义的。 std::size_t s 更有意义。
  • IntArray 是类模板没有意义。对我来说使用起来更有意义:

    class IntArray : public Array<int> { ... };
    

【讨论】:

  • 我不同意将实现放在标题中。这不是标题的想法,因此应尽可能避免。如果模板类只需要使用少量允许的模板参数,这显然是可能的,通常使用一个名为 MyClass_Specialization.h 的文件完成,该类 MyClass 实例化模板并包含在源代码的底部文件。正如您发布的链接中接受的答案一样。由于您在 SO 上有很多分数,我假设您知道这一点,但我建议您在答案中添加。
  • @Aziuth,我意识到可以将类模板的实现放在 .cpp 文件中,但我不向初学者推荐这种做法。
  • 非模板子类能否继承模板超类?使用模板类似乎非常复杂。我的代码在不使用模板的情况下完美运行。
  • @asilvester635,是的,它可以。使用模板(类模板和函数模板)肯定比普通的类或函数更复杂。随着您获得更多经验,它似乎会变得不那么复杂:)
  • @RSahu 感谢您的建议。
猜你喜欢
  • 2017-08-27
  • 2019-03-14
  • 1970-01-01
  • 2014-09-23
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
相关资源
最近更新 更多