繁体   English   中英

模板类变量作为非模板类​​的成员

[英]template class variable as member of a non template class

我不是专家C ++开发人员,我不确定是否可以做我想做的事情。

我有一个类似的模板类:

template < typename T >
class table
{
public
table ( AnotherClassPtr* handler, int s);
table<T>& operator<<(const T& table);
table<T>& operator>>( T& table);

...
}

我有一个标准班。 在这个类中,我想创建一些table对象。 es:

class A{
public:
 ...
AnotherClassPtr* pointer;
table<aCertainStruct> myTable;
...
}

它不起作用,因为我错过了table的默认构造函数。 但是我不能做一个默认的构造函数,因为我需要将一个指向AnotherClassPtr的指针传递给table类,该指针是在我要调用为table定义的构造函数之前在A类的构造函数中创建的。 es:

//inside the constructor of the A class.
....
pointer= getAnotherClassPtr();
table<aCertainStruct> myTable ( pointer, 42);
...

[尝试]下面的内容可以编译,但无法正常运行。 实际上,如果我尝试调用类表的某些功能,将无法正常工作。

class A{
public:
 ...
AnotherClassPtr* pointer;
table<aCertainStruct> myTable ( AnotherClassPtr*, unsigned int)
...
}

// in the constructor of the A class
....
pointer= getAnotherClassPtr();
table<aCertainStruct> myTable ( pointer, 42);
...

如我所说,这是行不通的;

问:是否可以将模板类变量创建为非模板类​​的成员? 或在其他workds中:是否可以在A类声明中定义一个table成员,然后定义在A构造函数中调用我的用户定义的构造函数的表对象?

我为我的英语不好而感到抱歉,因为它不是我的母语,我希望问题清楚。

提前致谢。

这就是为什么存在构造函数初始化器列表的原因:

class A{
public:
    A()
        : pointer(getAnotherClassPtr()), myTable(pointer, some_value)
    {}

    ...
    AnotherClassPtr* pointer;
    table<aCertainStruct> myTable;
    ...
};

这将初始化并“调用” table的参数化构造函数,而不是默认构造函数。


如今,使用相对较新的编译器,您还应该能够执行与A类第二次尝试类似的操作,但是必须使用“赋值”语法进行初始化,或者使用大括号{}括号() (因为括号用于成员函数):

table<aCertainStruct> myTable{pointer, some_value};

当然,这需要先初始化pointer

在这样的简单情况下,您可以使用成员初始化程序语法,而不是分配给(已经初始化的)成员。

class A
{
public:
    A() :
        pointer(getAnotherClassPtr()),
        myTable(pointer, 42)
    {}

    //...
    // pointer must come before myTable!
    AnotherClassPtr* pointer;
    table<aCertainStruct> mytable;
};

正如在类注释中指出的那样,如果在类定义中的pointer之前声明了mytable ,这将行不通。 初始化类成员的顺序始终取决于类声明它们的顺序,而不是构造函数的成员初始化器列表的顺序。 同样,如果getAnotherClassPtrA成员,则出于相同的原因,请确保将其标记为static或不使用pointer之前声明的A其他任何成员。

如果您还有其他原因想要以某种顺序声明类成员,或者如果初始化逻辑在其他方面更复杂,则针对此类问题的更通用解决方案是使用私有帮助器结构并将其委托给私有构造器:

class A
{
private:
    struct InitHelper;
public:
    A() : A(InitHelper()) {}
    // ...

    // Now member order doesn't matter.
    table<aCertainStruct> mytable;
    AnotherClassPtr* pointer;
    // ...

private:
    explicit A(InitHelper&& helper);
};

struct A::InitHelper
{
    AnotherClassPtr* pointer;
    unsigned int mytable_arg2;
    InitHelper();
};

inline A::InitHelper::InitHelper()
{
    // Actual logic here!
    // ...
    pointer = getAnotherClassPtr();
    mytable_arg2 = 42;
    // ...
}

inline A::A(InitHelper&& helper) :
    mytable_arg2(helper.pointer, helper.mytable_arg2),
    pointer(helper.pointer)
{}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM