これはC++初期化子リストの構文に関する質問です。C++イニシャライザリスト機能:メンバーを初期化せずに関数を呼び出す?
メンバオブジェクトコンストラクタに引数を渡さずに、関数をイニシャライザリストから呼び出すことはできますか?
以下に示すコード例は、同様の状況から言い換えるとパラコード化されていますか?
状況
- メンバ変数は、コンストラクタ引数として シングルトンへのポインタを取ります。
- メンバ変数は、そのクラスを含むコンストラクタの初期化子リストによって構築されます。
- 含まれるクラスを作成する前にシングルトンが作成されていません。
コード
#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;
}
コンパイルエラー
>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
質問
CLAから関数を呼び出す構文的には可能ですssコンストラクタの初期化子リストは、メンバオブジェクトのデフォルトでないコンストラクタへの引数なしで?
質問は学問好奇心のためです。私は少なくとも1つの他の解決策が含まれているクラスを作成する前に、シングルトンをインスタンス化することを知っています。
ありがとうございます。私はあなたの前にオラフの答えを得ましたが、コンマオペレーターに私を紹介してくれてありがとう。 – StoneThrow