È questo un modo legale per implementare impuri funzioni virtuali?
-
26-09-2019 - |
Domanda
Con "funzione virtuale impuro", intendo funzioni virtuali pure che offrono anche implementazioni (come descritto in http://www.gotw.ca/gotw/031.htm ) per scopi diagnostici.
Il modo kosher per la loro attuazione è quello di fare:
class Foo
{
public:
...
virtual void Bar() = 0;
};
void Foo::Bar() { assert(false); }
Ma questo è una specie di noioso, soprattutto per una classe ha un certo numero di metodi virtuali puri. Inoltre, è difficile garantire che qualcuno non aggiunge accidentalmente una nuova funzione virtuale pura senza aggiungere anche una corrispondente implementazione.
Idealmente quello che vorrei fare è:
class Foo
{
public:
...
virtual void Bar() = 0
{
assert(false);
}
};
ma lo standard C ++ non consente esplicitamente (sezione 10.4 / 2 nella ISO C ++ standard di 2003).
In alternativa, ho pensato a un trucco. Nell'intestazione Foo.h
:
#ifndef ABSTRACT_METHOD
#define ABSTRACT_METHOD = 0
#endif
class Foo
{
public:
...
virtual void Bar() ABSTRACT_METHOD;
};
e poi nel file di origine Foo.cpp
corrispondente:
#define ABSTRACT_METHOD { assert(false); }
#include "Foo.h"
...
in modo che si ottiene una singola implementazione compilato.
Sarebbe agendo in tal modo essere legale?
Soluzione
No, non è legale. La regola una definizione dice che una classe può avere più definizioni di un programma (da diverse unità di traduzione), ma tali definizioni devono tutti costituiti da sequenze identiche di gettoni (3,2 / 5). ABSTRACT_METHOD
è una pre-elaborazione di token (prima della sostituzione macro), ma non è abbastanza buono.
Così il vostro file cpp non può essere validamente utilizzato nello stesso programma come un altro cpp che include l'intestazione.
Altri suggerimenti
non posso rispondere se è valido o meno. Ma se l'utente della classe dichiara una classe derivata nel file sorgente, il compilatore non imporrà che Bar()
deve essere attuata in che classe derivata (perché non vedrà la = 0
). Immagino che questo da solo sarebbe un motivo per non farlo in questo modo.