【问题标题】:Use abstract within base expecting it to be a derived class?在基础中使用抽象期望它是派生类?
【发布时间】:2011-02-04 07:18:05
【问题描述】:

获取这个简单的代码:

class A{ 
  public: 
  virtual void foo() = 0; 
  void x(){ foo(); }
};
class B: public A{ foo(){ ... } };

main(){
  B b;
  b.x();
}

我想要的是构建一个抽象类,该类将具有一个函数,该函数将调用一个期望它在派生类中实现的函数

问题是我似乎无法使它工作,编译器说它无法编译,因为它找不到要在 x() 中执行的 foo() 的引用(或类似的东西) ) 的基类。这能行吗?谁能给我一个例子吗?

编辑:它似乎只是在“foo();”时不起作用位于 A 类(基类)的析构函数内...
这让我很困惑。 =[

EDIT2:这有多有趣。我刚刚创建了一个 callfoo(){ foo();现在它编译好了,但如果我尝试直接从基类 A 的析构函数中调用纯抽象函数,它会给我错误......奇怪。有人对此有任何想法吗? O_o

请问有什么帮助吗?

谢谢,
乔纳森

更新

它在析构函数之外工作。现在我只是糊涂了。

尝试将“foo()”放在 A(base) 类的析构函数中,至少对我来说不是编译...

有什么帮助吗?

【问题讨论】:

  • 我会回到这里接受有关此问题的任何答案,如果我做错与否,我在 vmware 内的 linux 盒子中使用 gcc 4.3.2...感谢所有答案到目前为止,我非常喜欢这个网站...
  • 一切都与效率有关。只有在构造 B 对象的 A 部分时,您对 B 本身一无所知(因此不能调用它的方法),才能实现创建和销毁对象的最有效方法。

标签: c++ class inheritance abstract


【解决方案1】:

它应该与一些语法修改一起工作。

#include <iostream>

class A { 
  public: 
  virtual ~A() {}
  virtual void foo() = 0; 
  void x() { foo(); }
};

class B: public A{ 
    void foo(){ std::cerr << "bingo!" << std::endl; } 
};

int main(){
  B b;
  b.x();
  return 0;
}

$ g++ -Wall -Weffc++ derived.cc 
$ ./a.out 
bingo!

这种技术是完全合法的。

【讨论】:

    【解决方案2】:

    没有什么能阻止你这样做:

    struct A {
        virtual ~A() {}
        virtual void f() = 0;
        virtual void g() { f(); }
    };
    
    struct B : A {
        void f() { std::cout << "B::f()" << std::endl; }
    };
    
    // ...
    A* a = new B;
    a->g(); // prints "B::f()"
    

    至于从析构函数(或构造函数)调用纯虚函数:不要!它会调用未定义的行为。

    §10.4/6

    可以从抽象类的构造函数(或析构函数)调用成员函数;对于从这样的构造函数(或析构函数)创建(或销毁)的对象,直接或间接地对纯虚函数进行虚调用(10.3)的效​​果是未定义的。

    【讨论】:

    • 我喜欢虚拟析构函数 touch :)
    • 我正在尝试创建一个必须具有“DeleteItens”作为抽象函数的类,该函数将在基类的析构函数中调用。但我仍然得到未定义的参考 =[
    • @Jonathan:你能用一个展示问题的例子来更新这个问题,或者就你遇到的问题提出一个具体的问题吗?
    • 我更新了这个问题,它有助于你理解我吗?我缺乏一些英语=[
    • 查看我添加的更新,应该会澄清它。主要问题是 - 你希望它从基础构造函数中做什么?调用派生类没有用,它的析构函数在基类的析构函数之前被调用。
    【解决方案3】:

    似乎您正在寻找的是Template Method pattern. 的实现

    您需要使用指针,以便利用多态性(从而避免消息... x 不是 B 的成员)

    #include <iostream>                                                             
    
    class A{  
      public: 
        virtual void foo() = 0;  
        virtual void x(){ foo(); }
    };  
    class B: public A{  
            void foo(){ std::cout<<"this is b"<<std::endl; } 
    };
    
    int main(){
     A* b= new B();
     b->x();
    
     return 0;
     }   
    

    【讨论】:

    • x() 是 B 的成员。它是从 A 公开继承的。
    【解决方案4】:

    理论上也可以,但你应该在 B 类的 foo() 中添加一个返回类型

    【讨论】:

      猜你喜欢
      • 2013-06-30
      • 2012-05-21
      • 2017-06-21
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 2015-03-23
      相关资源
      最近更新 更多