C ++初始化程序列表功能:调用函数而不初始化成员吗?

掷石

这是C ++的初始化列表语法的问题。

是否有可能从调用初始化列表函数,而不让其参数成员对象的构造函数?

下面列出的代码示例在工作时有类似的情况转述(paracoded?)。

情况

  • 成员变量需要一个指针到一个单作为构造器参数。
  • 成员变量由其包含类的构造函数中的初始化器列表构造。
  • 在构造包含类之前尚未创建单例。

编码

#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

问题

从语法构造上可以从类构造函数的初始值设定项列表中调用函数而无需成为成员对象的非默认构造函数的参数吗?

现在的问题是学术的好奇心。我知道至少有其他解决方案是在创建包含类之前实例化单例。

奥拉夫·迪斯切

您可以使用逗号运算符

在你的例子中

class Foo
{
public:
    Foo()
        : mContainer((SingletonService<OneOfMe>::InstallInstance(new OneOfMe),
                      SingletonService<OneOfMe>::Instance()))
    {}
    virtual ~Foo();
protected:
    Container mContainer;
};

请注意两个表达式之间的附加括号,否则它们将被解释为两个而不是一个参数。


解决此特定问题的另一种方法也可以是从中返回单例InstallInstance(),例如

template <class T>
class SingletonService {
public:
    static T *InstallInstance(T *pT) { LOG; return mpT = pT; }
};

然后

class Foo {
public:
    Foo()
        : mContainer(SingletonService<OneOfMe>::InstallInstance(new OneOfMe)) {}
    virtual ~Foo();
protected:
    Container mContainer;
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C ++初始化程序列表成员仍在调用默认构造函数?

C ++中的初始化程序列表和类初始化。我有无参数构造函数,但仍必须使用初始化列表?

C ++类成员初始化序列

C ++初始化成员数组

C ++中的初始化程序列表性能?

C ++初始化程序列表的元素比结构少

c ++ 11初始化程序列表作为数组

C ++中初始化程序列表的顺序

C ++初始化程序列表重载消除歧义

C ++在初始化列表中的基类初始化之前调用函数

C ++使用其他参数获取构造函数的初始化程序列表

C ++:使用RAII解决构造函数初始化程序列表依赖项

C#对象初始化程序-包括构造函数调用括号吗?

声明时新的C ++ 11成员初始化功能是否使初始化列表过时了?

C ++中的可调用类对象:没有匹配的函数来调用'std :: tuple <T> :: tuple(<括号包围的初始化程序列表>)'

为什么显式声明的构造函数阻止使用C ++ 11初始化列表进行成员初始化?

C ++内联初始化成员变量的正确方法

c ++:初始化成员结构的静态字段的正确方法

C++ 类:必须显式初始化成员

C ++使用构造函数参数初始化成员数组

C ++:在constexpr构造函数中初始化成员数组

C++ 如何使用隐藏的默认构造函数初始化成员?

如何在C ++中初始化成员的构造函数参数

构造函数是否必须在C ++中初始化成员变量?

C ++ 11默认类成员与初始化器列表同时初始化

C++初始化列表中多个成员的高效非平凡初始化

具有非静态成员初始化程序的类的C ++ 11聚合初始化

调用静态成员的方法以在C ++中进行初始化

C ++如何从值列表初始化向量成员