Dies ist eine Frage zur Syntax von C++ - Initialisierungslisten.C++ - Initialisiererlistenfunktionen: Aufruffunktionen ohne initialisierendes Member?
Ist es möglich, Funktionen aus Initialisierungslisten aufzurufen, ohne dass sie Argumente für Konstruktoren von Elementobjekten sind?
Das unten aufgeführte Codebeispiel ist paraphrasiert (paracodiert?) Aus einer ähnlichen Situation bei der Arbeit.
Die Situation
- eine Elementvariable nimmt einen Zeiger auf einen Singleton als Konstruktor Argument.
- Die Elementvariable wird von der Initialisierungsliste im Konstruktor der enthaltenden Klasse erstellt.
- Der Singleton wurde nicht erstellt, bevor die umschließende Klasse erstellt wurde.
Der Kodex
#include <iostream>
#define LOG { std::cout << __PRETTY_FUNCTION__ << std::endl; }
namespace
{
template <class T>
class SingletonService
{
public:
static T* Instance() { LOG; return mpT; }
static void InstallInstance(T* pT) { LOG; mpT = pT; }
static void DeleteInstance() { if (mpT) delete mpT; }
protected:
static T* mpT;
};
template <class T>
T* SingletonService<T>::mpT = NULL;
class OneOfMe
{
public:
OneOfMe() { LOG; };
virtual ~OneOfMe() { };
};
class Container
{
public:
Container(OneOfMe* pObj) { LOG; /* Do something with pObj */ }
virtual ~Container() { }
};
int GenerateNum()
{
return 42;
}
class Baz
{
public:
Baz(int num) : mNum(num) { LOG; }
virtual ~Baz() { }
protected:
int mNum;
};
class Bar
{
public:
Bar() : mBaz(GenerateNum()) { LOG; } // Perfectly OK to call function that is argument to member object's non-default ctor.
virtual ~Bar() { };
protected:
Baz mBaz;
};
class Foo
{
public:
Foo()
: SingletonService<OneOfMe>::InstallInstance(new OneOfMe) // Compile error
, mContainer(SingletonService<OneOfMe>::Instance()) { }
virtual ~Foo() { };
protected:
Container mContainer;
};
}
int main(int argc, char* argv[])
{
LOG;
Bar bar;
SingletonService<OneOfMe>::InstallInstance(new OneOfMe); // This works.
Container container(SingletonService<OneOfMe>::Instance()); // And this works.
SingletonService<OneOfMe>::DeleteInstance();
return 0;
}
Der Compiler-Fehler
>g++ main.cpp
main.cpp: In constructor ‘<unnamed>::Foo::Foo()’:
main.cpp:45: error: expected class-name before ‘(’ token
main.cpp:45: error: no matching function for call to
‘<unnamed>::Container::Container()’
main.cpp:37: note: candidates are:
<unnamed>::Container::Container(<unnamed>::OneOfMe*)
main.cpp:35: note:
<unnamed>::Container::Container(const<unnamed>::Container&)
main.cpp:45: error: expected ‘{’ before ‘(’ token
Die Frage
Ist es syntaktisch möglich, eine Funktion von einem cla anrufen SS-Konstruktor Initialisierungsliste ohne ein Argument zu einem Nicht-Standardkonstruktor des Mitgliedsobjekts zu sein?
Die Frage ist für akademische Neugier. Ich kenne mindestens eine andere Lösung, um das Singleton zu instanziieren, bevor die umschließende Klasse erstellt wird.
Danke; Ich habe die Antwort von Olaf vor deiner bekommen, aber danke dir auch, dass du mich dem Komma-Operator vorgestellt hast. – StoneThrow