1. ホーム
  2. c++

[解決済み] デフォルトコンストラクタを使用しないオブジェクト配列の初期化

2023-07-03 10:05:06

質問

#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()コンストラクタをpublicにせずに、この初期化を行う方法はあるでしょうか?

どのように解決するのですか?

いいえ。

しかし、なんと!もしあなたが 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 は、範囲を示す2つのイテレータを受け入れるために、本当に別の方法で設計されるべきです。