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

时间:2018-08-01 09:54:44

标签: c++ class templates constructor

我不是专业的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的默认构造函数。但是我无法创建默认的构造函数,因为我需要向table类传递指向AnotherClassPtr的指针,该指针是在类A的构造函数中创建的,我想在此之前调用该构造函数。为table定义。 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中:是否可以在table类声明中定义A成员,然后定义在A构造函数中调用我的用户定义的构造函数的表对象?

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

提前谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

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

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


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

table<aCertainStruct> myTable{pointer, some_value};

这当然需要首先初始化pointer

答案 1 :(得分:1)

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

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

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

如类注释中所述,如果在类定义的mytable之前声明pointer,则此方法将无效。初始化类成员的顺序始终取决于类声明它们的顺序,而不是构造函数的成员初始化器列表的顺序。另外,如果getAnotherClassPtrA的成员,请确保将其标记为static或不使用在A之前声明的pointer的任何其他成员,出于同样的原因。

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

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)
{}