繁体   English   中英

在 C/C++ 中使用派生类成员变量将参数传递给基本构造函数

[英]Passing arguments to Base constructor using Derived class member variables in C/C++

我正在构建一个类来控制一些具有几个不同版本的硬件。 由于版本种类繁多,某些参数需要进行硬编码,并且每个版本都不同。 但是,除了这些硬编码参数之外,所有版本都提供相同的功能。

我认为我会构建它的方式是使用一个包含所有所需方法的基类和派生类(DerivedV1、DerivedV2 等),在这里我只需将这些硬编码参数定义为成员变量,然后将它们作为构造参数传递给基类。

这是代码的一个最小示例:(这是部署在微控制器上的,因此使用数组而不是向量,也忽略了 std::cout 的使用,这里仅包含它来说明问题)

#include <iostream>
using namespace std;

void print_array(uint16_t *array, uint16_t size){
    cout<<"[ ";
    for(int i=0; i < size-1; i++){
      cout<<array[i]<<", ";
    }
    cout<<array[size-1]<<" ]"<<endl;
}


class BaseClass{
protected:
  std::string id_;
  uint16_t num_cats_;    
  uint16_t num_dogs_;     
  uint16_t *cat_mapping_;
  uint16_t *dog_mapping_; 
  uint16_t combinations_;

public:  
    BaseClass(string id, uint16_t num_cats, uint16_t num_dogs,
            uint16_t *cat_map, uint16_t *dog_map){

        cout<<"Base Constructor"<<endl;
        id_ = id;
        num_cats_ = num_cats;
        num_dogs_ = num_dogs;
        cat_mapping_ = cat_map;
        dog_mapping_ = dog_map;
        combinations_ = num_cats_*num_dogs_;
        cout<<"Num cats: "<<num_cats_<<endl;
        cout<<"Num dogs: "<<num_cats_<<endl;
        print_array(cat_mapping_, num_cats_);
        print_array(dog_mapping_, num_dogs_);
        cout<<"Combinations: "<<combinations_<<endl;
    }

    virtual ~BaseClass(){};

};


class DerivedClassV1 : public BaseClass 
{
private:
  uint16_t num_cats_ = 10;
  uint16_t cat_map_[10] = {31, 15, 20, 32, 13, 25, 19, 16, 28, 23};
  uint16_t num_dogs_ = 8;
  uint16_t dog_map_[8] = {5, 25, 23, 4, 13, 15, 14, 26};

public:
  DerivedClassV1(string id) : BaseClass(id, num_cats_, num_dogs_, cat_map_, dog_map_){
    cout<<"Derived Constructor";
  }
};


int main()
{
    DerivedClassV1 dummy("v1");
    return 0;
}

执行此代码会导致输出垃圾:

基础构造函数
猫数量:64
狗数量:64
[ 0, 0, 2, 0, 0, 0, 4781, 64, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 4704, 64, 0, 0, 3040, 64, 0 , 0, 42640, 13254, 32766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44869, 10268, 32576, 0, 0, 0, 0, 0, 426256, 426256, 0, 0, 44869, 10268, 32576 , 0, 0, 1, 0, 3456, 64, 0, 0, 0, 0, 0, 0, 13708, 48499 ]
[ 0, 0, 0, 0, 0, 0, 0, 4704, 64, 0, 0, 3040, 64, 0, 0, 42640, 13254, 32766, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 44869, 10268, 32576, 0, 0, 0, 0, 0, 42648, 13254, 32766, 0, 0, 0, 1, 0, 3456, 64, 0, 0, 0, , 0, 13708, 48499, 5513, 17381, 3040, 64, 0, 0, 42640, 13254, 32766, 0, 0, 0, 0, 0, 0, 0, 0, 09, 6, 18, 18, 18, 18, 39 , 13708, 57481, 17840, 484 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4704, 64, 0, 0, 42648, 132056, 132764 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3040, 64, 0, 0, 42640, 13254, 32766, 0, 0, 0, 0, 0, 3081 ]
组合:7936
派生构造函数

我在这里做错了什么? 为什么发送到 BaseClass 的参数不是派生类中定义的正确参数?

我应该以不同的方式做这件事吗? 任何帮助表示赞赏

你的程序的行为是未定义的。

从概念上讲, DerivedClassV1::cat_map_ &c。 在构造基类时不存在。

指向此类数组的指针(例如基类构造函数中的cat_map )实际上是悬空的。

你不能使用多态来产生合适的数组吗?

您可以使用模板将 DerivedClassV1 值传递给 BaseClass。 但是这些值必须是静态常量,因此它们在基类之前被初始化。

#include <iostream>
using namespace std;

void print_array(const uint16_t *array, uint16_t size){
    cout<<"[ ";
    for(int i=0; i < size-1; i++){
      cout<<array[i]<<", ";
    }
    cout<<array[size-1]<<" ]"<<endl;
}


template <class T>
class BaseClass {
protected:
  std::string id_;
  const uint16_t *cat_mapping_ = T::cat_map_;
  const uint16_t *dog_mapping_ = T::dog_map_; 
  uint16_t combinations_;

public:  
    BaseClass(string id){

        cout<<"Base Constructor"<<endl;
        id_ = id;
        combinations_ = T::num_cats_*T::num_dogs_;
        cout<<"Num cats: "<<T::num_cats_<<endl;
        cout<<"Num dogs: "<<T::num_dogs_<<endl;
        print_array(cat_mapping_, T::num_cats_);
        print_array(dog_mapping_, T::num_dogs_);
        cout<<"Combinations: "<<combinations_<<endl;
    }

    virtual ~BaseClass(){};
};


class DerivedClassV1 : public BaseClass<DerivedClassV1> 
{
public:
  static const uint16_t num_cats_ = 10;
  static constexpr uint16_t cat_map_[10] = {31, 15, 20, 32, 13, 25, 19, 16, 28, 23};
  static const uint16_t num_dogs_ = 8;
  static constexpr uint16_t dog_map_[8] = {5, 25, 23, 4, 13, 15, 14, 26};

public:
  DerivedClassV1(string id) : BaseClass(id){
    cout<<"Derived Constructor";
  }
};
constexpr uint16_t DerivedClassV1::cat_map_[10];
constexpr uint16_t DerivedClassV1::dog_map_[8];

暂无
暂无

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

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