【问题标题】:Changing array with function when parameter is class type c++当参数是类类型c ++时用函数更改数组
【发布时间】:2018-12-18 08:42:34
【问题描述】:

我知道它可能与此重复: Changing array inside function in C,但我仔细阅读了它,我想知道一种情况:

void addCustomer(Customer*** array, int length, char type) {
    for (int i = 0; i < length; i++) {

    Customer *c1 = new Customer();

    switch (type) {
    case '1':
        c1 = new LowCustomer();
        break;
    case '2':
        c1 = new MiddleCustsomer();
        break;
    case '3':
        c1 = new HighCustomer();
        break;
    case '4':
        c1 = new VIPCustomer();
        break;
    }

    (*array)[i] = c1;
}

LowCustomerMiddelCustomerHighCustomerVIPCustomer 类都派生自 Customer 类。

因此,由于我必须使用 new 关键字,因此数组现在必须是 ***。有没有更好的办法?因为我的代码在 c1 上使用0xcdcdcdcd 不断产生运行时错误。

我在main 中的代码如下所示:

Customer*** low = new Customer**[10];
addCustomer(low, 10, 'c');

附:哦!顺便说一句,我知道使用 vector 会更容易,但我真的想为此使用指针。

【问题讨论】:

  • 请使用std::unique_ptrstd::shared_ptr并尝试使用std::vector
  • 这不会解决你的问题,但在效率方面,而不是做Customer *c1 = new Customer();然后指定类型,你为什么不尝试使用策略设计模式 。例子很多(鸭子是最容易理解的)。
  • 何时删除切换前创建的未使用的“客户”实例?您只需覆盖指针并泄漏您的内存。 “***”很火,以前没见过!为什么你标记你的问题 c++?你这里只用C?故意的?哦,“新”是我能看到的唯一 c++...
  • @Hellowhatsup 你能详细说明为什么 std::vector 不能被接受吗?

标签: c++


【解决方案1】:
Customer*** low = new Customer**[10];

这只会创建一个包含 10 个 Customer** 的数组。这些是未初始化的指针。在(*array)[i] = c1; 中,您正在取消引用这些未初始化的指针,这是未定义的行为,会导致您看到运行时错误(如果幸运的话)。

您在这里也严重泄漏了内存。如果你 new 某事,你最终必须 delete 它。但是Customer *c1 = new Customer(); 没有对应的delete,您只是稍后覆盖(或尝试)该指针。

如果你真的想坚持使用指针,这基本上可以工作(使用对 Customer* 数组的引用):

Customer** low = new Customer*[10];
addCustomer(low, 10, 'c');

// ...

void addCustomer(Customer**& array, int length, char type)
{
  for (int i = 0; i < length; i++)
  {
    Customer* c1;
    switch (type) {
    case '1':
        c1 = new LowCustomer();
        break;
    case '2':
        c1 = new MiddleCustsomer();
        break;
    case '3':
        c1 = new HighCustomer();
        break;
    case '4':
        c1 = new VIPCustomer();
        break;
    default:
        // Error handling...
  }

  array[i] = c1;
}

您也可以坚持使用三星级方法,但 low 必须是 Customer**,然后将指向低的指针传递给 addCustomeraddCustomer(&amp;low, 10, 'c');

不用说,使用向量。通过查看函数签名,不可能知道只有中间的* 应该是一个数组。

【讨论】:

    【解决方案2】:

    我明确无视您对std::vector 的评论,因为我没有看到您避免这种情况的充分理由。 std::vector 很好地管理分配内存的内存。通过将std::unique_ptr 存储到其中,您还可以对创建的实例进行正确的内存管理。

    其他一些变化包括:

    • 按值而不是输出参数返回
    • 保留向量,以获得向量的单个内存分配
    • 使用 size_t 而不是 int 来匹配向量的 size_type 的大小

    建议的更改:

    • 用范围枚举(枚举类)替换“char”

    Code on Compiler Explorer

    #include <vector>
    #include <memory>
    
    struct Customer
    {
        virtual ~Customer() = default;
    };
    
    struct LowCustomer : Customer {};
    struct MiddleCustomer : Customer {};
    struct HighCustomer : Customer {};
    struct VIPCustomer : Customer {};
    
    using Customers = std::vector<std::unique_ptr<Customer>>;
    
    Customers createCustomer(size_t length, char type)
    {
        auto values = Customers{};
        values.reserve(length);
        for (size_t i = 0; i < length; i++)
        {
            switch (type)
            {
            case '1':
                values.emplace_back(std::make_unique<LowCustomer>());
                break;
            case '2':
                values.emplace_back(std::make_unique<MiddleCustomer>());
                break;
            case '3':
                values.emplace_back(std::make_unique<HighCustomer>());
                break;
            case '4':
                values.emplace_back(std::make_unique<LowCustomer>());
                break;
            default:
                values.emplace_back(std::make_unique<Customer>());
                break;// Error handling...
            }
        }
    
        return values;
    }
    
    int main(int, char**)
    {
        auto low = createCustomer(10, 'c');
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-23
      • 2017-05-02
      • 2019-03-20
      • 2018-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多