Использовать абстрактный внутри базы, ожидая, что он будет производным классом? - PullRequest
2 голосов
/ 05 апреля 2010

возьмите этот простой код:

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

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

Я хочу создать абстрактный класс, который будет иметь функцию, которая будет вызывать функцию, ожидающую, что она будет реализована в производном классе

Вопрос в том, что я не могу заставить это работать, компилятор говорит, что не может скомпилировать, потому что не может найти ссылку (или что-то в этом роде) на foo () для выполнения в x ( ) базового класса. Может ли это работать? Кто-нибудь может дать мне пример этого?

РЕДАКТИРОВАТЬ: кажется, что это просто не работает, когда "foo ();" находится внутри деструктора класса А (базового) ...
Это просто запутало меня. = [

EDIT2: как интересно это получилось. Я только что создал callfoo () {foo (); } и теперь он компилируется нормально, но если я попытаюсь вызвать чистую абстрактную функцию непосредственно из деструктора Базового класса A, это даст мне ошибки ... странно. Кто-нибудь имеет представление об этом? O_o

любая помощь по этому вопросу, пожалуйста?

Спасибо
Jonathan

Обновление

Он работал вне деструктора. Теперь я просто запутался.

Попробуйте поместить "foo ()" в деструктор класса A (base), по крайней мере, для меня это не компиляция ...

любая помощь плз?

Ответы [ 4 ]

4 голосов
/ 05 апреля 2010

Ничто не мешает вам сделать это:

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 голос
/ 05 апреля 2010

Похоже, что вам нужна реализация шаблона шаблона .

Вам нужно использовать указатели, чтобы воспользоваться преимуществами полиморфизма (таким образом избегая сообщения ... 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;
 }   
1 голос
/ 05 апреля 2010

Должно работать с несколькими синтаксическими модификациями.

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

Эта техника совершенно легальна.

0 голосов
/ 05 апреля 2010

Теоретически, это работает так же хорошо, хотя вы должны добавить тип возврата к foo () в классе B

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...