【问题标题】:Why does default constructor is called even when I am calling the parameterized constructor?为什么即使在调用参数化构造函数时也会调用默认构造函数?
【发布时间】:2020-10-10 12:48:33
【问题描述】:

我有一个类,我正在使用参数化构造函数创建它的一个对象。在此期间,参数化构造函数和默认构造函数都已被调用。

这是我的 sn-p:

class student {
    string name;
    int age;
public:
    student() {
        cout << "Calling the default constructor\n";
    }
    student(string name1, int age1) {
        cout << "Calling the parameterized const\n";
        name = name1;
        age = age1;
    }
    void print() {
        cout << " name : " << name << " age : " << age << endl;
    }
};

int main()
{
    map<int, student> students;
    students[0] = student("bob", 25);
    students[1] = student("raven", 30);

    for (map<int, student>::iterator it = students.begin(); it != students.end(); it++) {
        cout << "The key is : " << it->first ;
        it->second.print();
    }
    return 0;
}

当我执行这个 sn-p 时,我的输出是:

调用参数化的 const
调用默认构造函数
调用参数化的 const
调用默认构造函数
关键是:0 姓名:鲍勃年龄:25
关键是:1 姓名:乌鸦年龄:30

所以,我想明白,如果我调用的是参数化构造函数,为什么在参数化构造函数之后调用了默认构造函数?

【问题讨论】:

  • 不相关,您可以通过从成员初始化列表中的 student 构造函数按值参数移动构造您的成员变量来进一步改进此代码(您目前根本没有使用)。对 age 成员没有影响,但它避免了字符串复制。
  • '因为 std::map [] 运算符做了一些非常愚蠢的事情,证明即使是 C++ 设计背后的主体也不是完美的。
  • @Bathsheba 另一种方法是抛出异常,这也不理想。但我同意这是一个让大多数用户感到惊讶的问题。

标签: c++ class stdmap default-constructor parameterized-constructor


【解决方案1】:

因为如果指定的键不存在,std::map::operator[] 将首先插入一个默认构造的student。然后插入的student 从临时的student 中分配,例如student("bob", 25)

返回对映射到与 key 等效的键的值的引用,如果这样的键不存在,则执行插入。

您可以改用insert

students.insert({0, student("bob", 25)});
students.insert({1, student("raven", 30)});

【讨论】:

    【解决方案2】:

    students[0] 正在使用它的默认构造函数自动构造对象。 students[0] = 使用复制赋值运算符,student("bob", 25) 调用 parameterized constructor

    你可以使用:

    studets.insert(pair<int, student>(0, student("bob", 25)));
    

    或:

    studets.emplace(0, student("bob", 25));
    

    避免使用默认构造函数。

    From the standard:

    T& operator[](const key_type& x);
    

    效果:相当于:return try_emplace(x).first->second;

    T& operator[](key_type&& x);
    

    效果:相当于:return try_emplace(move(x)).first->second;

    T&       at(const key_type& x);
    const T& at(const key_type& x) const;
    

    返回:对对应于 x in* *this 的 mapped_type 的引用。

    抛出:如果不存在此类元素,则为 out_of_range 类型的异常对象。

    复杂度:对数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 2021-08-31
      • 2013-03-13
      • 1970-01-01
      相关资源
      最近更新 更多