【问题标题】:Creating Vector elements without calling a constructor在不调用构造函数的情况下创建 Vector 元素
【发布时间】:2018-03-15 13:19:16
【问题描述】:

假设我有两个级别的汽车和服务。是否可以为汽车和服务类的矢量对象(注意:我不知道是否实际上被称为矢量对象)创建元素。一旦创建了两个元素,我只想稍后调用汽车类构造函数以调用服务构造函数来获取用户信息?

如果可能的话,是否可以不必将Service构造函数更改为方法?

   using namespace std; // I know this is not the best, prof wants us to use it

   class Car { Car() { //Get data from user } };

   class Service { Service(){ //Get data from user } };

   int main () {

       int num;
       vector<Car> car; 
       vector<Service> service;

       car.push_back(Car{});
       service.push_back();

       for (int i = 0; i < car.size(); i++) 
            car[i].display(i);
       cout << endl << car.size() + 1 << ". exit";
       cin >> num;
       service[num].Service::Service();

   }

【问题讨论】:

  • 您在寻找std:vector&lt;std::optional&lt;Service&gt;&gt; 吗?见std::optional
  • 请描述你试图更好地解决的问题(问题描述,最小化,而不是你试图在代码中做的事情)
  • 在构造对象时不要从用户那里获取输入,而是编写一个函数来询问您需要什么,然后将其传递给对象的构造函数。然后您可以返回该对象并使用它将其分配给您想要的向量元素。
  • 你应该开始阅读一本 c++ 初学者书籍。什么是继承,什么是 OOP,以及虚拟方法可以为您做什么。 “稍后”调用构造函数绝对是 c++ 工作方式的错误想法。所以你应该从基础开始
  • 在构造函数运行之前,您不能拥有对象。为什么不将//Get data from user 移出默认构造函数并移到函数Car getCarFromInput()Service getServiceFromInput() 中?

标签: c++ class object vector elements


【解决方案1】:

我建议使用std::map 而不是std::vector,您的任务自然会选择该选项。通过使用它,您将只存储有效的服务元素。

   map<int,Service> service;

   car.push_back(Car{});

   for (int i = 0; i < car.size(); i++) 
        car[i].display(i);
   cout << endl << car.size() + 1 << ". exit";
   cin >> num;
   service[num]; //Service constructor will be called

【讨论】:

    【解决方案2】:

    我认为您正在寻找这样的东西:

    class Car {
    private:
        std::string _make;
        std::string _model;
        std::string _vinNumber;
    
        std::size_t _year;
    
    public:
        Car() : _year( 0 ) {} // default
        Car( const std::string& make, const std::string& model, 
             const std::string& vinNumber, const std::size_t& year ) :
          _make( make ), _model( model ), 
          _vinNumber( vinNumber ), _year( year ) {
        }
    
        void setCarInfo( const std::string& make, const std::string& model,
                         const std::string& vinNumber, const std::size_t& year ) {
            _make      = make;
            _model     = model;
            _vinNumber = vinNumber;
            _year      = year;
        }
    
        std::string makeOf() const { return _make; }
        std::string modelOf() const { return _model; }
        std::string vinNumberOf() const { return _vinNumber; }
        std::size_t yearOf() const { return _year; }
    
    };
    
    class Service {
    private:
        std::string _dealership;
        std::size_t _currentMiles;
    
    public:
        Serivce() {}
    
        std::string dealershipOf() const { return _dealership; }
        std:size_t  currentMilesOf() const { return _currentMiles; }
    
        void setOrChangeDealership( const std::string& dealership ) {
            _dealership = dealership;
        }
    
        void setOrChangeCurrentMiles( std::size_t miles ) {
            _currentMiles = miles;
        }
    
        void setOrChangeCurrentMiles( const std::size_t& miles ) {
            _currentMiles = miles;
        }
    };
    
    int main() {
        std::vector<Car> cars;
        std::vector<Service> services;
    
        // you can add Car to vector by either default constructor 
        // to be filled out later or by user defined constructor
        cars.push_back( Car( "Honda", "Civic", "75273250323XMD252AG9", 2017 ) );
        // or
        cars.push_back( Car() );
        // then you can at some point in time update elements in container
        cars[i].setCarInfo( "Dodge", "Charger", "9259356M325D2680A217B", 2015 );
    
        // As with the service class there is only a "default" constructor
        services.push_back( Service() );
        // Service's members will have to be updated manually and later.
    
        return 0;
    }
    

    无论您使用什么容器,或者即使您有一个类对象的单个实例;将调用该类的CTOR。唯一不会的方法是如果 A:您在类中将其声明为 protectedprivate 会阻止声明与继承和多态一起使用的类,或者如果您将构造函数声明为已删除功能:SomeClass() = delete。如果没有编译器隐式调用或您显式调用其构造函数,就不可能拥有类实例。

    即使是这么简单的事情:

    class A {
    public:
        int x;
    };
    
    int main() {
    
       A a;
       a.x = 5;
    
       return 0;
    }
    

    编译器将在a 上调用A() 在幕后的A a; 行,所以它实际上看起来像这样:

     A a();
    

    使用其默认构造函数。

    【讨论】:

      【解决方案3】:

      从 C++11 开始,您可以对向量和其他容器进行列表初始化。

      http://en.cppreference.com/w/cpp/language/list_initialization

      这意味着,您可以在初始化时将元素枚举放入向量中。

      您可以在其中使用自己的类构造函数:

      std::vector<Car> cars {Car(...), Car(...), Car(...)}; //C++11
      

      由于我还不能评论你的问题,这是你所期望的吗?

      【讨论】:

      • 我想为我的两个类创建对象,这两个类都有一个构造函数。我希望两个对象都添加一个元素,尽管我只希望调用汽车类构造函数而不要调用服务类构造函数。
      猜你喜欢
      • 1970-01-01
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2015-07-21
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      相关资源
      最近更新 更多