没有默认构造函数的对象数组初始化

新手上路,请多包涵
#include <iostream>
class Car
{
private:
  Car(){};
  int _no;
public:
  Car(int no)
  {
    _no=no;
  }
  void printNo()
  {
    std::cout<<_no<<std::endl;
  }
};
void printCarNumbers(Car *cars, int length)
{
    for(int i = 0; i<length;i++)
         std::cout<<cars[i].printNo();
}

int main()
{
  int userInput = 10;
  Car *mycars = new Car[userInput];
  for(int i =0;i < userInput;i++)
         mycars[i]=new Car[i+1];
  printCarNumbers(mycars,userInput);
  return 0;
}

我想创建一个汽车阵列,但出现以下错误:

 cartest.cpp: In function ‘int main()’:
cartest.cpp:5: error: ‘Car::Car()’ is private
cartest.cpp:21: error: within this context

有没有办法在不公开 Car() 构造函数的情况下进行初始化?

原文由 Dan Paradox 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 609
2 个回答

没有。

但是看!如果您使用 std::vector<Car> ,就像您应该使用的那样(永远不要使用 new[] ),那么您可以准确指定应该如何构造元素*。

*好吧。您可以指定要复制的值。


像这样:

 #include <iostream>
#include <vector>

class Car
{
private:
    Car(); // if you don't use it, you can just declare it to make it private
    int _no;
public:
    Car(int no) :
    _no(no)
    {
        // use an initialization list to initialize members,
        // not the constructor body to assign them
    }

    void printNo()
    {
        // use whitespace, itmakesthingseasiertoread
        std::cout << _no << std::endl;
    }
};

int main()
{
    int userInput = 10;

    // first method: userInput copies of Car(5)
    std::vector<Car> mycars(userInput, Car(5));

    // second method:
    std::vector<Car> mycars; // empty
    mycars.reserve(userInput); // optional: reserve the memory upfront

    for (int i = 0; i < userInput; ++i)
        mycars.push_back(Car(i)); // ith element is a copy of this

    // return 0 is implicit on main's with no return statement,
    // useful for snippets and short code samples
}

使用附加功能:

 void printCarNumbers(Car *cars, int length)
{
    for(int i = 0; i < length; i++) // whitespace! :)
         std::cout << cars[i].printNo();
}

int main()
{
    // ...

    printCarNumbers(&mycars[0], mycars.size());
}

注意 printCarNumbers 确实应该设计不同,以接受两个表示范围的迭代器。

原文由 GManNickG 发布,翻译遵循 CC BY-SA 2.5 许可协议

首先,我想澄清一下 printCarNumbers 函数中的代码中存在错误,您正在尝试使用 std::cout 将 void 发送到标准输出,如下所示:

 void printCarNumbers(Car *cars, int length)
{
    for(int i = 0; i < length; i++)
         std::cout << cars[i].printNo();
}

因为 printNo() 用于打印,所以直接调用它:

 for(int i = 0; i < length; i++)
   cars[i].printNo();

让我们回到主题,您正在尝试使用 new 分配一个对象数组,如下所示:

 Car *mycars = new Car[userInput];

但是使用这种语法,您实际上试图分配一个具有 userInput 大小的对象数组(这就是我们想要的),但问题是它试图为每个对象调用默认构造函数,并且默认构造函数被声明为私有的,所以它找不到它,这就是你得到那个错误的原因:

 cartest.cpp:5: error: ‘Car::Car()’ is private

而不是你需要这样做:

 Car *mycars = (Car*) ::operator new (sizeof(Car));
// allocates memory by calling: operator new (sizeof(Car))
// but does not call Car's constructor

如评论中所述,调用 new 以这种方式为您分配内存而不调用默认构造函数,有关更多详细信息,请查看 new 运算符

现在,如果要调用参数化构造函数,则需要分别为每个对象调用它,如下所示:

 for(int i =0; i < userInput; i++)
    new (&mycars[i]) Car(i + 1);  // does not allocate memory -- calls: operator new (sizeof(Car), &mycars[i])
                                  // but constructs an object at mycars[i]

你现在可能会感到困惑,因为我们再次调用了 new ,但是这个 new 的语法并没有分配任何内存,它只是调用索引对象的构造函数。

这是任何想要测试的人的完整功能代码:

 #include <iostream>

class Car
{
    private:
        Car(){};
        int _no;
    public:
        Car(int no)
        {
          _no=no;
        }
        void printNo()
        {
          std::cout << _no << std::endl;
        }
};

void printCarNumbers(Car *cars, int length)
{
    for(int i = 0; i < length; i++)
        cars[i].printNo();
}

int main()
{
  int userInput = 10;

  Car *mycars = (Car*) ::operator new (sizeof(Car));

  for(int i =0;i < userInput;i++)
    new (&mycars[i]) Car(i+1);

  printCarNumbers(mycars,userInput);

  return 0;
}

我知道我来晚了,但也许有人会觉得这很有用,如果有任何错误的陈述,请随时纠正我。

原文由 Holy semicolon 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题