开发者

Use abstract within base expecting it to be a derived class?

开发者 https://www.devze.com 2022-12-26 04:45 出处:网络
take this simple code: class A{ public: virtual void foo() = 0; void x(){ foo(); } }; class B: public A{ foo(){ ... } };

take this simple code:

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

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

What I want is to build an abstract class that will have a function that will call a function expecting it to be implemented in the derived class

The question is that I can't seem to make that work, the compiler says it can't compile because it can't find the reference(or something like that) to the foo() to be executed in x() of the base class. Can this work? Can anyone give me an example of this?

EDIT: It seems that it just doesn't work when the "foo();" is inside the destructor of class A(the base one)...

It just got me confused. =[

EDIT2: how interesting this got. I just created a callfoo(){ foo(); } and now it compiles ok, but if I try to call the pure abstract function directly from within the destructor of Base class A, it gives me errors... weird. Anyone has any idea of this? O_o

any help on this please?

Thanks,

Jonathan

Update

It worked outside the destructor. Now I just got confused.

Try pu开发者_运维技巧tting the "foo()" inside the destructor of the A(base) class, at least for me is not compiling...

any help plz?


There is nothing preventing you from doing that:

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()"

As for calling a pure virtual function from the destructor (or constructor): Don't! It invokes undefined behaviour.

§10.4/6:

Member functions can be called from a constructor (or destructor) of an abstract class; the effect of making a virtual call (10.3) to a pure virtual function directly or indirectly for the object being created (or destroyed) from such a constructor (or destructor) is undefined.


It should work with a few syntactic modifications.

#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!

This technique is perfectly legal.


Seems that what you are looking for is an implementation of the Template Method pattern.

You need to use pointers, in order to take advantage of polymorphism (thus avoiding the message ... x is not a member of 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;
 }   


Well in theory that works just as fine, you should though add a return type to foo() on class B

0

精彩评论

暂无评论...
验证码 换一张
取 消