【问题标题】:How to call default and copy constructor on the same object in the following C++ code?如何在以下 C++ 代码中对同一对象调用默认构造函数和复制构造函数?
【发布时间】:2018-03-09 16:57:00
【问题描述】:

我要做什么?

我正在尝试在对象的默认构造函数中获取用户输入,并在复制构造函数中进行比较,如果前一个对象和当前对象具有相同的品牌名称。

有什么问题?

我无法调用同一个对象的默认构造函数和复制构造函数。

我的代码:

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

class Scooty {

    int cc ;
    string model, brand;
    bool goodBrands();

  public:

    Scooty () : cc(0), model(""), brand("") {

        cout << "\n Enter the following scooty details: \n\n";

        cout << "\n \t Brand: ";
        cin >> brand;
        transform(brand.begin(), brand.end(), brand.begin(), :: tolower);

        cout << "\n \t Model: ";
        cin >> model;
        transform(model.begin(), model.end(), model.begin(), :: tolower);

        cout << "\n \t CC: ";
        cin >> cc;
    }

    Scooty (Scooty &s) { if (brand == s.brand) cout << "You will get a discount!\n"; }

    void computeDataAndPrint ();
 };

 bool Scooty :: goodBrands() {

    if (brand == "honda" || brand == "tvs" || brand == "yamaha")
        return true;
    return false;
 }

 void Scooty :: computeDataAndPrint () {

    if (cc > 109 && goodBrands())
        cout << "\n Good Choice!\n";
    else
        cout << "\n Its okay!\n";
 }

 int main() {

    Scooty s;
    Scooty s1, s1(s)  // This gives error

    s.computeDataAndPrint();

    return 0;
 }

【问题讨论】:

  • 但是,为什么?你不能多次构造东西。确定一个比较它们的函数就足够了吗?
  • 我想你误解了复制构造函数的用途
  • 这是否意味着一个对象一次只能调用一个构造函数?
  • 您在“默认构造函数”和“复制构造函数”中所做的操作应移至 2 个单独的函数“getUserInput”和“checkDiscount”,并在使用默认构造函数构造对象后调用它们
  • @Doda:在 C++11 及更高版本中,是的(使用委托构造函数)。在早期版本中,没有。

标签: c++ copy-constructor default-constructor


【解决方案1】:

您的复制构造函数不会调用您的默认构造函数。

C++11 引入了委托构造函数的概念。构造函数可以在自己的初始化列表中调用同一类的另一个构造函数。例如:

Scooty (const Scooty &s)
    : Scooty() // <-- add this
{
    if (brand == s.brand)
        cout << "You will get a discount!\n";
}

这允许构造函数利用同一类的另一个构造函数执行的初始化。

在 C++ 的早期版本中,初始化列表只能调用直接基类和数据成员的构造函数,因此必须在构造函数主体可以根据需要调用的单独函数/方法中执行常见的初始化。例如:

class Scooty {
    int cc;
    string model;
    string brand;

    void init() {
        cout << "\n Enter the following scooty details:- \n\n";
        cout << "\n \t Brand:";
        cin >> brand;
        transform(brand.begin(), brand.end(), brand.begin(), ::tolower);
        cout << "\n \t Model:";
        cin >> model;
        transform(model.begin(), model.end(), model.begin(), ::tolower);
        cout << "\n \t CC:";
        cin >> cc;
    }

    ...

public:
    Scooty () : cc(0) {
        init(); // <-- here
    }

    Scooty (const Scooty &s) : cc(0) {
        init(); // <-- here
        if (brand == s.brand)
            cout << "You will get a discount!\n";
    }

    ...
};

int main() {
    Scooty s;
    Scooty s1(s);
    ...
    return 0;
}

【讨论】:

    【解决方案2】:

    在你的 main() 函数中:

    `Scooty s;  `   you create a variable `s` <br/>
    

    Scooty s1, s1(s) // 你创建了一个变量s1,现在你试图创建另一个同名变量。这是一个错误

    试试:

    Scooty s, s1;
    S1 = Scooty(s)
    

    我希望你知道怎么做。

    正确的程序或至少工作......

    #include <iostream>
    #include <bits/stdc++.h>
    
    using namespace std;
    
    class Scooty {
        int cc ;
        string model, brand;
        bool goodBrands();
    
    public:
    
    Scooty () {
         cc = 0, brand = "", model = "";
         cout << "\n Enter the following scooty details: \n\n";
         cout << "\n \t Brand: ";
         cin >> brand;
         transform(brand.begin(), brand.end(), brand.begin(), :: tolower); //STRING LOWER FUNCTION ..
    
         cout << "\n \t Model: ";
         cin >> model;
         transform(model.begin(), model.end(), model.begin(), :: tolower); //STRING LOWER FUNCTION ..
    
         cout << "\n \t CC: ";
         cin >> cc;
    }
    Scooty (Scooty &s) : Scooty() { //Initializing the object first then comparing, [using two constructors]
         if (brand == s.brand) cout << "You will get a discount!\n";
    }
    void computeDataAndPrint ();
    };
    
    bool Scooty :: goodBrands() {
    
       if (brand == "honda" || brand == "tvs" || brand == "yamaha")
         return true;
       return false;
    }
    
    void Scooty :: computeDataAndPrint () {
       if (cc > 109 && goodBrands())
           cout << "\n Good Choice!\n";
       else
           cout << "\n Its okay!\n";
    }
    
    int main() {
       Scooty s;               // Calling default constructor for constructor of S.
       //    s.computeDataAndPrint();
       Scooty s1(s);          // Calling copy constructor which firstly calls the default constructor then executes the copy constructors body.
       return 0;
      }
    

    这个程序在逻辑上是不正确的,因为它违反了复制构造函数的用途。复制构造函数应该用于将一个对象复制到另一个对象中,并且对于这样的操作您应该重载 == 运算符。

    【讨论】:

      【解决方案3】:

      构造函数只是将实例初始化为有效状态。首先,您没有问这个问题,但我会修改您的默认构造函数,以简单地获取 cc、型号和品牌,并将所有 I/O 移动到一个单独的函数中:

      class Scooty {
          // etc...
      
        public:
          // default constructor
          Scooty (int cc, string model, string brand) : cc(cc), model(model), brand(brand) {}
      
          // a correctly-written copy constructor (not necessary since the implicit copy constructor does exactly this)
          Scooty (const Scooty &s) : cc(s.cc), model(s.model), brand(s.brand) {}
      
          // etc...
       };
      
      
      Scooty getScootyFromUserInput() {
          int cc;
          string brand, model;
      
          cout << "\n Enter the following scooty details:- \n\n";
      
          cout << "\n \t Brand:";
          cin >> brand;
          transform(brand.begin(),brand.end(), brand.begin(), :: tolower);
      
          cout << "\n \t Model:";
          cin >> model;
          transform(model.begin(),model.end(), model.begin(), :: tolower);
      
          cout << "\n \t CC:";
          cin >> cc;
      
          return Scooty(cc, brand, model);
      }
      

      您的if (brand == s.brand) 语句当然不属于复制构造函数 - 当您创建副本时,品牌当然总是相同的。你应该做的是把它变成一个辅助函数,或者一个类方法来检查折扣是否适用:

      class Scooty {
        public:
          bool checkDiscount(const Scooty &) const;
      }
      
      bool Scooty::checkDiscout(const Scooty &scooty) const {
          return brand == scooty2.brand;
      }
      

      然后像这样编写你的 main 函数:

      int main() {
          Scooty s = getScootyFromUserInput();
          Scooty s1 = getScootyFromUserInput();
      
          if (s.checkDiscout(s1)) {
              cout << "You will get a discount!\n";
          }
      }
      

      【讨论】:

      • 我知道我可以用函数来做到这一点。我只是想知道我是否可以在不使用任何辅助函数的情况下对构造函数做同样的事情。
      • 不,你不能。这不是构造函数的用途,如果你试图以这种方式使用它们,你几乎肯定会遇到麻烦。
      猜你喜欢
      • 1970-01-01
      • 2020-05-14
      • 1970-01-01
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 2017-07-28
      • 2014-03-24
      • 1970-01-01
      相关资源
      最近更新 更多