【问题标题】:Inheritance and conversion between 2 classes failed c++2个类之间的继承和转换失败c ++
【发布时间】:2014-01-05 08:51:44
【问题描述】:

我有 Signal 和 Image 类,这两个类都有同名但输入参数和输出参数不同的方法。是否允许?

template <class T> class Signal {
public:
    Signal<T> zeroPadding(Signal<T>);
}

template <class T> class Image:public Signal<T>
{
public:
    Image(void);
    ~Image(void);
    Image(int,int);
    Image(int,int,double);
    Image(int,int,double,double);
    Signal<T> zeroPadding(Image<T>);

    template <class T> Image<T>::Image(int width,int height):Signal(width,height) {}

    template <class T> Image<T>::Image(int width,int height,double dt):Signal(width,height,dt) {}

    template <class T> Image<T>::Image(int width,int height,double dt,double t0 ):Signal(width,height,dt,t0) {}


    template <class T> Signal<T> Image<T>::zeroPadding(Image<T> im2){
         Image<T> i1 =(*this);
         Image<T> i2 =im2;

         if (i1.getHeight()==i2.getHeight()){
          ....
          return(im2);
         }
    }    
}   

int main() {

    Image<int> *a=new Image<int>(2,3);
    Image<int> *b=new Image<int>(1,3);
    (*a).zeroPadding(*b); //when I try to debug it failed with error error LNK2019:
                          //unresolved external symbol 
                          //"public: __thiscall Signal<int>::~Signal<int>(void)" (??1?$Signal@H@@QAE@XZ)
                          //referenced in function 
                          //"public: __thiscall Image<int>::~Image<int>(void)" (??1?$Image@H@@QAE@XZ)
}

另一个问题:如果我想调用主函数 (*a).Signal::zeroPadding(*b) 怎么办?如何将 (*a) 和 (*b) 转换为 Signal?

【问题讨论】:

  • 请实现 Signal zeroPadding(Signal)
  • 您昨天已经发布了此代码。它仍然在语法上被破坏了。
  • 减一表示再次发帖(假设@jrok 是对的)
  • 我在 Signal 类中实现了 zeroPadding,而我的 Signal 类与 Image 类不在同一个文件中,但我将它们放在一起,这样您就可以在两个类中看到声明。

标签: c++ inheritance implicit-conversion base derived-class


【解决方案1】:

由于链接器如何使用模板,您的实现应该与声明位于同一文件中。你会得到 LNK2019,因为该方法只是 declared 而不是 defined,编译器不知道如何处理它。

转换是可能的。您需要将指向 a 或 b 的指针显式转换为 Signal。

【讨论】:

  • 我在 Signal 类中实现了 zeroPadding 方法,并且实现与声明在同一个文件中,但我没有放在这里只是为了显示两个类,但我仍然有同样的错误。
  • 如果我在主函数中添加行,例如 Signal *pB = static_cast*>(a);或类似 Signal *pb=a;我仍然得到错误。
【解决方案2】:

是的,这是允许的。如果成员函数未声明为虚拟,则要调用的函数由调用者的类确定。在您的情况下,zeroPadding 函数由派生类 Image 类型调用,因此 Image 类中的函数将重载基类。

还有你的错误信息

unresolved external symbol 
public: __thiscall Signal<int>::~Signal<int>(void)" (??1?$Signal@H@@QAE@XZ)referenced in function 
public: __thiscall Image<int>::~Image<int>(void)" (??1?$Image@H@@QAE@XZ)

暗示你已经为SignalImage模板类声明了析构函数,但是没有实现它们,所以会出现链接错误;

对于您的最后一个问题,由于 *a 和 *b 是类 Signal 的派生类实例,因此您可以轻松地将它们转换为 Signal。每个简单的类型转换方法都可以做到这一点。static_cast&lt;Signal&lt;int&gt; &gt;(*a) 或直接使用(Signal)(*a) 就足够了。

更新:似乎这是一个关于单独编译的非常古老但常见的问题。 :)

什么是单独编译?一个简单的解释方法是,如果您在编写模板类时将实现代码与声明文件放在不同的源文件中,那么您正在使用单独的编译。有一个关键字export 专门针对这种情况,但编译器支持不是那么好。

建议将实现代码一起放入声明文件中,或者将实现文件包含在模板类的头文件中。

Templates and separate compilation

http://www.cs.uofs.edu/~bi/se516/chapter4/tsld022.htm

http://www.cplusplus.com/forum/beginner/73735/

【讨论】:

  • 当我创建类时,我得到了 Signal(void)、~Signal(void)、Image(void)、~Image(void) 和 Image.cpp 和 Signal.cpp 两个类的构造函数和析构函数我得到了他们的实施;例如对于 Image.cpp 中类 Image 的构造函数,我得到了模板 Image::Image(void) { }
  • 我需要实现一些额外的东西吗?
  • 你使用了单独编译?
  • 这样的转换有效 Signal *pB=static_cast *>(a);信号 *pB1=static_cast *>(b);所以现在如果我想调用这样的东西 (*pB).zeroPadding(*pB1);我得到了同样的错误
  • @user3094708 ,这与类型无关。试试谷歌seperate compilation。将您的实现代码放入头文件中,这应该可以解决您的问题。
猜你喜欢
  • 2023-03-31
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 2021-08-25
  • 2016-08-31
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
相关资源
最近更新 更多