簡體   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