【问题标题】:C++ overload constructor with const array and initializer_list带有 const 数组和 initializer_list 的 C++ 重载构造函数
【发布时间】:2017-08-19 13:26:53
【问题描述】:

我有一个类,它在构造函数中将引脚“列表”作为参数。 现在,这个“列表”只是一个 const 数组 (const unsigned int (&pins)[N])。 我想以一种可以使用 initializer_list 和 (const) 数组的方式重载构造函数。
我可以让它与单独的类一起工作,但我无法将它们组合起来。

我的测试类的基本结构:

#include <iostream>
#include <cstring>
using namespace std;

class X
{
  public:
    X(... pins);
    ~X();
    void print() {
        for (unsigned int i = 0; i < length; i++)
            cout << pins[i] << ' ';
    }

  private:
    (const) unsigned int *pins;
    const size_t length;
};

A 类(使用 std::initializer_list)

  public:   
    A(initializer_list<unsigned int> pins)
        : length(pins.size()) {
        this->pins = (unsigned int *)malloc(sizeof(unsigned int) * pins.size());
        memcpy(this->pins, pins.begin(), sizeof(unsigned int) * pins.size());
    }
    ~A() {
        free(pins);
    }
  private:
    unsigned int *pins;

B 类(使用数组)

  public:
    template <size_t N>
    B(unsigned int (&pins)[N])
        : length(N) {
        this->pins = pins;
    }
  private:
    unsigned int *pins;

C 类(使用 const 数组)

  public:
    template <size_t N>
    C(const unsigned int (&pins)[N])
        : length(N) {
        this->pins = pins;
    }
  private:
    const unsigned int *pins;

这让我可以做以下事情:

A a({1, 2, 3});

unsigned int pb[] = {4, 5, 6};
B b(pb);

const unsigned int pc[] = {7, 8, 9};
C c(pc);

a.print();
b.print();
c.print();

这会按预期打印1 2 3 4 5 6 7 8 9

如何将这些不同的构造函数组合到一个类中? 我希望能够以上面显示的三种方式中的任何一种来初始化对象。

如果我将pins 设为const,我将无法执行memcpy(pins, ...) 之类的操作,如果我不将其设为const,我将无法使用 const 数组作为参数构造函数。

(目标平台是 Arduino,因此不支持大多数花哨且占用大量内存的 C++11 技巧。)

【问题讨论】:

  • B 和 C 可以组合我认为如果您通过初始化程序而不是在构造函数的函数内部分配它,那么长度(N),引脚(引脚)。 const 成员只能通过初始化程序设置,不能在构造函数内部设置。 - 请注意,您正在存储一个指针。否则总是可以选择使用允许设置它的 mutable 关键字,只需确保将其保密,以免在构造后有任何东西会弄乱它
  • 所以等等 - 你希望 pins 有时是指向堆分配内存的拥有指针,但有时是指向外部提供数组的非拥有指针?析构函数如何知道它是否应该调用free(pins)
  • 是的。但我愿意接受更好的建议。我只需要一个引脚列表,我想像A a({1, 2, 3}); 一样内联初始化它,以及使用数组。

标签: c++ arrays c++11 initializer-list


【解决方案1】:

大概是这样的:

class X
{
  public:
    X(std::initializer_list<unsigned int> aPins)
        : storage(aPins), length(aPins.size()) {
      pins = length ? &storage[0] : nullptr;
    }

    template <size_t N>
    X(unsigned int (&aPins)[N])
        : length(N) {
        pins = aPins;
    }

    template <size_t N>
    X(const unsigned int (&aPins)[N])
        : length(N) {
        pins = aPins;
    }

    void print() {
        for (unsigned int i = 0; i < length; i++)
            std::cout << pins[i] << ' ';
    }

  private:
    const unsigned int* pins;
    const size_t length;
    std::vector<unsigned int> storage;
};

Demo

【讨论】:

  • 谢谢,但遗憾的是,Arduino 不支持使用向量。
  • 但是引脚总是const 我想说的是 OPs 问题
  • @tttapa 将storage 设为普通指针,然后使用malloc 进行分配。 std::vector 的使用不是示例的基础。
  • @FilipKočica 为什么这是个问题?你认为 OP 试图做什么被这个事实排除在外?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
相关资源
最近更新 更多