webentwicklung-frage-antwort-db.com.de

Einen Verweis auf Member auf NULL in C++ initialisieren

Ist es möglich, ein Referenzelement in C++ auf NULL zu initialisieren?
Ich versuche so etwas: 

class BigClass
{
private:
  Object m_inner;
public:
  const Object& ReadOnly;
  BigClass() : ReadOnly(NULL)
  {
    Do stuff.
  }
};

Ich weiß, dass ich dies tun kann, wenn ich "ReadOnly" auf eine echte Referenz eines Objekts initialisiere, aber wenn ich dort "NULL" einfügen möchte, erhalte ich den Fehler: 

"kann nicht von 'int' in 'const Object &' konvertieren

Wie kann ich das lösen?

19
Idov

Nein, Referenzen können in C++ nicht NULL sein.1

Mögliche Lösungen sind:

  • verwenden eines Zeigers anstelle einer Referenz.
  • mit einer Dummy Object-Instanz, die verwendet werden kann, um "kein Objekt" anzuzeigen.

[1] Vom C++ 11-Standard :

[dcl.ref] [...] Eine Nullreferenz kann in einem genau definierten Programm nicht existieren, da die einzige Möglichkeit, eine solche Referenz zu erstellen, darin besteht, sie an das durch Dereferenzieren erhaltene Objekt zu binden ein Nullzeiger, der undefiniertes Verhalten verursacht.

26

Sie können dies nicht "lösen". Verwenden Sie einen Zeiger, wenn dieses Mitglied auf nichts zeigen soll.

Referenzen müssen auf ein reales Objekt initialisiert werden, sie können nicht "auf irgendwo zeigen".

10
Mat

Es kann gemacht werden, aber es ist fast sicher eine extrem schlechte Idee . Dies geschieht durch die Dereferenzierung eines entsprechend typisierten NULL-Zeigers, der bereits zeigt, dass dies eine schlechte Idee ist: Sie erreichen an dieser Stelle ein undefiniertes Verhalten, das jedoch in der Regel zum "Arbeiten" neigt.

In C++ sollen Referenzen immer auf ein tatsächliches Objekt verweisen. Dies unterscheidet sich von anderen Programmiersprachen, bei denen "Referenzen" tatsächlich das Äquivalent von pointer in C++ sind (normalerweise ohne Zeigerarithmetik). Was Sie wahrscheinlich tatsächlich wollen (Sie haben leider nicht gesagt, was Sie versuchen, es zu erreichen, sondern nach einer Lösung für ein Problem gefragt, das wahrscheinlich Teil eines fehlgeleiteten Ansatzes ist), verwenden Sie stattdessen einen Zeiger:

Object const* const readOnly;
BigClass(): readOnly(0) {}
7
Dietmar Kühl

Verwenden Sie einen Zeiger: - Const Object * pReadOnly;

2
QuentinUK

Es ist hilfreich beim Schreiben von Komponententests. Das ist der only Ort, an dem es gemacht werden sollte, aber dort ist es ziemlich hilfreich.

 Bar& bar(*static_cast<Bar*>(0));
 MockClass mock; // derives from RealClass
 mock.foo(bar);

Hier teste ich Code, der MockClass verwendet, nicht MockClass selbst.

Es ist kein Allheilmittel, aber es kann helfen. GoogleMock könnte Ihr Freund sein, wenn Sie "konkrete" Kurse verspotten.

struct Bar;
struct RealClass {
  int& x_;
  double& y_;
  RealClass(int& x, double& y) :x_(x), y_(y) {}
  virtual void foo(Bar&);
};
struct MockClass: public RealClass {
  MockClass(): RealClass(*(int*)0, *(double*)0) {}
  MOCK_METHOD1(foo, void(Bar&));
};
0
cdunn2001