2010-04-05 53 views
2

采取这种简单的代码:在基础中使用抽象期望它是派生类?

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

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

我要的是建立一个抽象类,将有会调用一个函数期待它在派生类中

的问题是,实现的功能我似乎无法完成这项工作,编译器称它无法编译,因为它无法找到引用(或类似的内容)到foo()以在基类的x()中执行。这可以工作吗?任何人都可以给我一个这样的例子吗?

编辑:它似乎只是不工作时,“foo();”在A级(基础级)的破坏者之内......
它让我感到困惑。 = [

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

对此有任何帮助吗?

感谢,
乔纳森

更新

它的工作的析构函数之外。现在我只是感到困惑。

尝试把“富()”的A(基地)类的析构函数里面,至少对我来说不是编译...

任何帮助PLZ?

+0

在哪里的问题? – 2010-04-05 00:14:46

+0

我会回到这里接受任何关于这个问题的答案,如果我做错了或不是,我正在使用gcc 4.3.2在vmware内的一个Linux机器中...感谢所有答案,到目前为止,我喜欢这个网站非常多... – Jonathan 2010-04-05 00:45:56

+0

这是关于效率。只有在构建B对象的A部分时,才能创建和销毁对象的最有效方法是对B本身一无所知(因此不能称之为方法)。 – baol 2010-04-05 00:54:45

回答

4

没有什么阻止你这样做:

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)的效​​果是未定义的。

+0

我喜欢虚拟析构触摸:) – baol 2010-04-05 00:23:36

+0

我想创建一个类,必须有一个“DeleteItens”作为一个抽象函数,将在基类的析构函数内调用。但我仍然得到未定义的参考= [ – Jonathan 2010-04-05 00:31:36

+0

@Jonathan:好像你问了一个错误的问题:) – baol 2010-04-05 00:35:01

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! 

这种技术是完全合法的。

1

好像你正在寻找的是的Template Method pattern.

您需要使用指针,以充分利用多态性(这样就避免了消息的实现...x不是B类的()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; 
} 
+1

x()是B的成员。它是从A公开继承的。 – 2010-04-05 01:37:58

0

井理论作品一样精致,你应该加入虽然返回类型为foo