【问题标题】:template class variable as member of a non template class模板类变量作为非模板类​​的成员
【发布时间】:2018-08-01 09:54:44
【问题描述】:

我不是专业的 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 类,该指针是在我想调用为 @987654327 定义的构造函数之前在 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);
...

正如我所说,这不起作用;

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

对不起,我的英语不好,不是我的母语,我希望问题很清楚。

提前致谢。

【问题讨论】:

    标签: c++ class templates constructor


    【解决方案1】:

    这就是为什么存在构造函数初始化列表

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

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


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

    table<aCertainStruct> myTable{pointer, some_value};
    

    这当然需要先初始化pointer

    【讨论】:

      【解决方案2】:

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

      class A
      {
      public:
          A() :
              pointer(getAnotherClassPtr()),
              myTable(pointer, 42)
          {}
      
          //...
          // pointer must come before myTable!
          AnotherClassPtr* pointer;
          table<aCertainStruct> mytable;
      };
      

      如类注释中所述,如果 mytable 在类定义中的 pointer 之前声明,则此方法无效。初始化类成员的顺序始终取决于类声明它们的顺序,而不是构造函数的成员初始化器列表的顺序。此外,如果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)
      {}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-25
        • 2012-05-25
        • 2023-03-31
        • 2019-04-12
        • 2012-01-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多