Object array initialization without default constructor

后端 未结 11 1939
误落风尘
误落风尘 2020-11-22 04:20
#include 
class Car
{
private:
  Car(){};
  int _no;
public:
  Car(int no)
  {
    _no=no;
  }
  void printNo()
  {
    std::cout<<_no<

        
相关标签:
11条回答
  • 2020-11-22 04:56

    In C++11's std::vector you can instantiate elements in-place using emplace_back:

      std::vector<Car> mycars;
    
      for (int i = 0; i < userInput; ++i)
      {
          mycars.emplace_back(i + 1); // pass in Car() constructor arguments
      }
    

    Voila!

    Car() default constructor never invoked.

    Deletion will happen automatically when mycars goes out of scope.

    0 讨论(0)
  • 2020-11-22 04:58

    One way to solve is to give a static factory method to allocate the array if for some reason you want to give constructor private.

    static Car*  Car::CreateCarArray(int dimensions)
    

    But why are you keeping one constructor public and other private?

    But anyhow one more way is to declare the public constructor with default value

    #define DEFAULT_CAR_INIT 0
    Car::Car(int _no=DEFAULT_CAR_INIT);
    
    0 讨论(0)
  • 2020-11-22 05:01

    You can use in-place operator new. This would be a bit horrible, and I'd recommend keeping in a factory.

    Car* createCars(unsigned number)
    {
        if (number == 0 )
            return 0;
        Car* cars = reinterpret_cast<Car*>(new char[sizeof(Car)* number]);
        for(unsigned carId = 0;
            carId != number;
            ++carId)
        {
            new(cars+carId) Car(carId);
        }
        return cars;
    }
    

    And define a corresponding destroy so as to match the new used in this.

    0 讨论(0)
  • 2020-11-22 05:02

    Good question. I had the same question, and found it here. The real answer is, @Dan-Paradox, there is no standard syntactical way of doing it. So, all these answers are a variety of alternatives to get around the problem.

    I read the answers myself, and didn't particularly find any of them perfect for my personal convention. The method that I'll probably stick with is using a default constructor and a set method:

    class MyClass
    {
      int x,y,z;
    public:
      MyClass(): x(0), y(0), z(0) {}
      MyClass(int _x,int _y,int _z): x(_x), y(_y), z(_z) {} // for single declarations
      void set(int _x,int _y,int _z)
      {
        x=_x;
        y=_y;
        z=_z;
      }
    };
    

    The standard initialization constructor is still there, so I can still initialize it normally if I don't need more than one, but if otherwise, I have a set method which sets all the variables that are initialized in the constructor. Thus I could do something like this:

    int len = 25;
    MyClass list = new MyClass[len];
    for(int i = 0; i < len; i++)
      list[i].set(1, 2, 3);
    

    This works fine and flows naturally, without making code look confusing.


    Now that's my answer for those wondering how to declare an array of objects that need to be initialized.

    For you specifically, you're trying to give an array of cars identities, which I'd suppose you want to always be unique. You could do it with my method I explained above, and then in the for loop use i+1 as the argument sent to the set method - but from what I've read in your comments, it seems like you want the ids more internally initiated, so that by default each Car has a unique id, even if someone else uses your class Car.

    If this is what you want, you can use a static member:

    class Car
    {
      static int current_id;
      int id;
    public:
      Car(): id(current_id++) {}
    
      int getId() { return id; }
    };
    int Car::current_id = 1;
    
    // ...
    
    int cars=10;
    Car* carlist = new Car[cars];
    
    for(int i = 0; i < cars; i++)
      cout << carlist[i].getId() << " "; // prints "1 2 3 4 5 6 7 8 9 10"
    

    In this way, you don't have to worry at all about initiating the identities since they are managed internally.

    0 讨论(0)
  • 2020-11-22 05:04

    You can create an array of pointers.

    Car** mycars = new Car*[userInput];
    for (int i=0; i<userInput; i++){
        mycars[i] = new Car(...);
    }
    
    ...
    
    for (int i=0; i<userInput; i++){
        delete mycars[i];
    }
    delete [] mycars;
    

    or

    Car() constructor does not need to be public. Add a static method to your class that builds an array:

    static Car* makeArray(int length){
        return new Car[length];
    }
    
    0 讨论(0)
提交回复
热议问题