我不是专业的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
构造函数中调用我的用户定义的构造函数的表对象?
我为我的英语不好而感到抱歉,这不是我的母语,我希望问题清楚了。
提前谢谢。
答案 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
,则此方法将无效。初始化类成员的顺序始终取决于类声明它们的顺序,而不是构造函数的成员初始化器列表的顺序。另外,如果getAnotherClassPtr
是A
的成员,请确保将其标记为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)
{}