代码之家  ›  专栏  ›  技术社区  ›  geraldCelente

无法将变量声明为类型,因为以下虚拟函数是抽象的

  •  1
  • geraldCelente  · 技术社区  · 13 年前

    我有以下代码

    等级.h

    #ifndef CLASSES_H
    #define CLASSES_H
    
    #include <iostream>
    using namespace std;
    
    
    
    template< class T1, class T2>
    class class1
    {
          public:
                 virtual void method1(int) const =0;
                 virtual void method2(class1&) const =0;
    };
    
    
    template< class T1>
    class class2:public class1<T1,int>
    {
          public:
                 void method1(int) const;
                 void method2(class2&) const;
    };
    
    
    template< class T1>
    void class2<T1>::method1(int i) const
    {
         cout<<"class2::method1 - before Call %i"<<endl;
         cout<<"class2::method1 - after Call"<<endl;
    }
    
    template< class T1>
    void class2<T1>::method2(class2& c2) const
    {
         cout<<"class2::method2 - before Call"<<endl;
         cout<<"class2::method2 - after Call"<<endl;
    }
    
    #endif
    

    主.cpp

    #include <cstdlib>
    
    #include <iostream>
    using namespace std;
    
    #include "Classes.h" 
    
    int main(int argc, char *argv[])
    {
        class2<int> c2;
    
        c2.method1(0);
        c2.method2(c2);
    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    基本上,C1是一个接口类,因此它的方法是纯虚拟的。遇到的问题是Medhod2传递类本身的实例(接口为class1,实现此类接口的类为class2)。

    因此,Method2具有签名

    void method2(class1&) const;
    

    在第1类和

    void method2(class2&) const;
    

    在第2类中。

    这就是我在编译时出现以下错误的原因。

    main.cpp: In function `int main(int, char**)':
    main.cpp:12: error: cannot declare variable `c2' to be of type `class2<int>'
    main.cpp:12: error:   because the following virtual functions are abstract:
    Classes.h:14: error:  void class1<T1, T2>::method2(class1<T1, T2>&) const [with
    T1 = int, T2 = int]
    make: *** [main.o] Error 1
    

    如何解决此问题?

    有人能告诉我吗?谢谢

    2 回复  |  直到 13 年前
        1
  •  2
  •   metal    13 年前

    您的问题是虚拟签名需要匹配(返回类型可以是协变的,但在其他情况下签名应该是相同的)。更改类2的 void method2(class2&) const; 到 void method2(class1&) const; .

    或者,隐藏虚拟方法并提供替换方法:

    class class2
    {
        // must be implemented since pure virtual, but now private
        void method2(class1&) const; 
    public:
        void method1(int) const;
        void method2(class2&) const;
    };
    
        2
  •  1
  •   Walter    13 年前

    你有一个 设计问题 : class1::method2(class1&) const 必须为 任何 与账单匹配的参数,即每个对类型的引用 class1 如果 class2 只能实现 method2() 对于类型的参数 第2类 ,它不仅在语法上而且在逻辑上都是不完整的:它无法处理预期用途

    class2 A;
    class1*B = method_returning_pter_to_class1_object();
    A.method2(*B);                         // intended usage of virtual function
    

    (如果你不打算这样使用,那么你的设计 类别1 有缺陷。)

    当然你可以用 dynamic_cast 如果参数实际为类型,则调用特殊行为 class2& ,即。

    void class2::method(class1&x) const
    {
      class2*x2 = dynamic_cast<class2*>(&x);
      if(x2)
        apply_method_taking_class2(*x2);
      else
        apply_method_for_other_than_class2_object(x);
    }
    

    但这可能会导致一些运行时惩罚。