采用这个简单的代码:
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();现在它编译好了,但是如果我尝试直接从Base类A的析构函数中调用纯抽象函数,它会给我错误......很奇怪。任何人都知道这个吗? O_O
对此有任何帮助吗?
谢谢,
乔纳森
更新
它在析构函数之外工作。现在我感到困惑。
尝试将“foo()”放在A(基类)类的析构函数中,至少对我来说是不编译...
任何帮助PLZ?
答案 0 :(得分: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)的效果是未定义的。
答案 1 :(得分: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 :(得分:1)
似乎您正在寻找的是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;
}
答案 3 :(得分:0)
从理论上讲,它的效果一样好,但你应该在B类的foo()中添加一个返回类型