Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 派生类中出错';<;中没有名为my_data的类型;基类>';_C++_Inheritance_Boost_Constructor_Composition - Fatal编程技术网

C++ 派生类中出错';<;中没有名为my_data的类型;基类>';

C++ 派生类中出错';<;中没有名为my_data的类型;基类>';,c++,inheritance,boost,constructor,composition,C++,Inheritance,Boost,Constructor,Composition,在我的代码中,我使用了一个模板化的多维容器类array\u dyn,它有一个属性my\u data,它是一个std::vector 为了保持事物的可分离性,我使用自己的类bisArray,该类继承自array\u dyn: typedef array_dyn<T> super_type; typedef typename super_type::index_t index_t; template < typename Sizes >

在我的代码中,我使用了一个模板化的多维容器类
array\u dyn
,它有一个属性
my\u data
,它是一个
std::vector

为了保持事物的可分离性,我使用自己的类
bisArray
,该类继承自
array\u dyn

typedef array_dyn<T>                   super_type;
typedef typename super_type::index_t   index_t;

template < typename Sizes >
bisArray( dirs a_dir, Sizes const& a_sizes={} ): 
        super_type ( a_dir, a_sizes ),   super_type::my_data( super_type::size()) {}
template < typename Sizes >
bisArray( Sizes const& a_sizes={} ): 
        super_type ( dir_fwd, a_sizes ), super_type::my_data( super_type::size()) {}
然后出现一条错误消息

no type named my_data in struct 'array_dyn<int>' 
结构“array\u dyn”中没有名为my\u data的类型
以前关于这个错误的StackOverflow帖子提到了循环定义和转发声明;但这不是我在这里要做的。我只是从
array\u dyn
继承,它有一个属性
my\u data
,但是当我用派生类bisArray创建一个对象时,它说它的基类没有这个属性

我是否使用了错误的继承机制?还是错误的访问方法?

简短回答: 不能在派生类的构造函数中初始化基类成员

您可能希望尝试类似的方法(假设my_数据具有合适的setter方法):

模板
bisArray(dirs a_dir,size const&a_size={}):
super_类型(a_目录,a_大小){
super_type::my_data.set_size(super_type::size());
}
更长的版本,我能从中找到的最好解释是第12.6.1.10段:

在非委托构造函数中,初始化按以下顺序进行:

-首先,并且仅针对最派生类(1.8)的构造函数,虚拟基类按照它们在基类有向无环图的第一次从左到右遍历中出现的顺序进行初始化,其中“从左到右”是基类在派生类基类规范列表中的出现顺序

-然后,直接基类按照它们在基规范列表中出现的声明顺序进行初始化(无论mem初始值设定项的顺序如何)

-然后,按照类定义中声明的顺序初始化非静态数据成员(同样,与mem初始值设定项的顺序无关)

-最后,执行构造函数主体的复合语句

现在,这听起来有点绕圈子了,但非静态数据成员按照类定义中声明它们的顺序初始化的约束意味着您不能在派生类中初始化基类成员。

您可能不应该(ab)使用继承。。。 问题:为什么对
bisArray
使用继承

是否要向
array\u-dyn
添加完全可以在
array\u-dyn
的公共界面中编写的额外功能?在这种情况下,添加非成员函数以提供该功能,而不是继承和添加成员函数。所以不是

template<class T>
class bisArray: public array_dyn<T>
{
public:
     void doCoolStuffThatBoostDoesNotProvide() const;
};
如果您想将
super\u type::my\u data
设置为另一个值,而不是
super\u type
构造函数所做的值,只需将这样一条语句放在构造函数的主体中即可。但是从Boost代码和您的代码来看,这里似乎并不需要

... 或者使用工厂函数来实现这两个方面的最佳效果 不过,如果
bisArray
所做的只是创建一个默认构造函数,该构造函数采用C-array样式参数
dir\u fwd
,为什么不放弃继承,编写两个非成员工厂函数,返回带有相应构造函数参数的
array\u dyn

template<typename T, typename Sizes>
make_fortran_array_dyn(Sizes const& a_sizes={} )
{
    return array_dyn<T>(dir_rev, a_sizes);
}

template <typename T, typename Sizes >
make_c_array_dyn( Sizes const& a_sizes={} )
{
     return array_dyn<T>(dir_fwd, a_sizes);
}     
模板
生成fortran数组(大小常量和大小={})
{
返回数组的大小(dir\u rev,a\u size);
}
模板
make_c_array_dyn(size const&a_size={})
{
返回数组_dyn(dir _fwd,a _size);
}     
你可以这样称呼它:

auto c = make_c_array_dyn<double>(your_sizes);
auto f = make_fortran_array_dyn<double>(your_sizes);
auto c=make\u c\u array\u dyn(您的大小);
自动f=生成fortran数组(您的大小);

我认为问题在于,您只能在mem-initializer-list中初始化自己类的成员。啊,谢谢您的简短回答!好的,因为super_type::my_data是一个std::vector,我想那就是my_data.resize()?我能让它工作的唯一方法是使用
super_type::my_data.resize(super_type::size())--知道为什么需要
超级类型::
吗?新类继承了
myu数据
,因此不需要这样做?@alle\u meije必须通过键入
this->
来消除依赖基类(
myu数据
的基类
array\u dyn
在这种情况下取决于模板
T
)的歧义,
array\u-dyn::
或其别名
super\u-type::
。注意VisualC++将让你摆脱它,但是在G++/CLAN上,标准在这一点上被强制执行。要了解您的观点:[1]我们的想法是向bisArray添加更多功能(如前所述,它已部分实现),这可能需要一个新类(因此,不初始化构造函数中的基类成员的继承是可行的)[2]array_dyn不从vector继承,但它从box_domain继承(在没有存储的情况下提供索引)。[3]为什么组合比继承更好/更安全?这与性能有关吗?[4]工厂示例看起来与组合的作用相同?@alle_meije[1]初始化基本成员最好通过基本构造函数完成,如上所示。如果新功能可以通过
array\u dyn
的公共接口实现,最好编写非成员函数..[4]工厂方法不需要一个新的类模板
bisArray
,只需根据构造函数定义一个非成员函数模板
make_C_array\u dyn
。@alle_meije[2]/[3]:是一个严重的设计错误,但很难在这个空白内解释。有几个项目专门用于它。@alle_meije a&S:a中的两件事)“从类型继承会导致名称查找引入函数
template<class T>
void doCoolStuffThatBoostDoesNotProvide(array_dyn<T> const& s);
template<class T>
class bisArray
{
public: 
     void doCoolStuffThatBoostCannotImplement() const;
private:
     some_fancy_type s_;
     array_dyn<T> a_;
};
template
  < typename Sizes
  >
array_dyn( dirs a_dir, Sizes const& a_sizes={})
: super_t( a_dir, a_sizes)
, my_data( super_t::size())
{
}
// note use explicit keyword for single-argument constructors
template<typename Sizes>
explicit bisArray( dirs a_dir, Sizes const& a_sizes={} )
: super_type(a_dir, a_sizes) 
{}

template < typename Sizes >
bisArray( Sizes const& a_sizes={} )
: super_type(dir_fwd, a_sizes)
{}     
template<typename T, typename Sizes>
make_fortran_array_dyn(Sizes const& a_sizes={} )
{
    return array_dyn<T>(dir_rev, a_sizes);
}

template <typename T, typename Sizes >
make_c_array_dyn( Sizes const& a_sizes={} )
{
     return array_dyn<T>(dir_fwd, a_sizes);
}     
auto c = make_c_array_dyn<double>(your_sizes);
auto f = make_fortran_array_dyn<double>(your_sizes);