【问题标题】:C++ initializing constC++ 初始化常量
【发布时间】:2018-06-28 21:08:45
【问题描述】:

我需要能够在构造函数中初始化一个 const 成员,每次创建一个新对象时它都会计数。我在学校被展示了它是如何工作的,但我一直在出错。这与复制构造函数有关。

这是代码和编译器错误:

class kunde {
public:
    kunde(string name, int alter);
    kunde(const kunde& orig);
    ~kunde();
    int GetAlter() const;
    string GetName() const;
    const int GetKnr() const;

private:
    string name;
    int alter;

    const int knr;

    static int cnt;
    static int MaxKnr;
};

int kunde::cnt = 0;
int kunde::MaxKnr = 1000;

kunde::kunde(string name, int alter):knr(MaxKnr++) {
    this->name = name;
    this->alter = alter;
}

kunde::kunde(const kunde& orig):knr(MaxKnr++){
    this->name = orig.name;
    this->alter = orig.alter;
}

kunde::~kunde() {
}

int kunde::GetAlter() const {
    return alter;
}

string kunde::GetName() const {
    return name;
}

const int kunde::GetKnr() const {
    return knr;
}
main.cpp:在函数'int main(int,char**)'中: main.cpp:35:15:错误:使用已删除的函数 'kunde& kunde::operator=(const kunde&)' v[0] = v[1]; ^ 在 main.cpp:17:0 包含的文件中: kunde.h:19:7: 注意:'kunde& kunde::operator=(const kunde&)' 被隐式删除,因为默认定义格式不正确: 类昆德{ ^~~~~ kunde.h:19:7: 错误:非静态 const 成员 'const int kunde::knr',不能使用默认赋值运算符

【问题讨论】:

  • knr 需要是 const 吗?
  • 如果您遇到构建错误,请告诉我们。将它们(作为文本)完整地复制粘贴到问题正文中。
  • 关于knr的常量,如果它是一种序列号来唯一识别“kunde”(我想这是德语的“客户”?)那么它没有意义.如果您制作副本,则两个副本都是相同客户的,不是吗?为同一个客户设置不同的客户编号是没有意义的。
  • 您的问题在于 赋值运算符,而不是复制构造函数。您的错误是指您未向我们展示的代码v[0] = v[1]。如果您需要将knr 设为const,则无法进行默认分配,因为assigning 意味着正在更改,而const 禁止更改。
  • @user3821856:首先你说knr在通过赋值复制对象时必须增加。然后你说它应该在创建对象时设置,然后保持不变。这是自相矛盾的。您需要下定决心并有意义地描述knr 是什么以及何时应该改变(或改变)。

标签: c++ constructor copy constants


【解决方案1】:

knr 应该是一个帐号。每次您创建一个对象时,它都会创建一个新的 const 帐号并保留。

如 cmets 中所述,由于 knrconst,因此编译器无法为该类生成默认的复制赋值 operator=,这正是编译器对 v[0] = v[1]; 语句的抱怨:

注意:'kunde& kunde::operator=(const kunde&)' 被隐式删除,因为默认定义格式错误

const成员一经初始化就无法重新分配,因此无法复制。

vector 中的元素必须是 CopyAssignableCopyConstructible(至少在 C++11 之前),但你的类没有可行的复制赋值 operator=,所以它不是 @987654334 @(在 C++11 中也不是 MoveAssignable,因为也无法生成可行的移动赋值 operator=)。

解决方案是实现忽略knr 的复制分配operator=(以及可选的移动分配operator=),例如:

class kunde {
public:
    kunde(string name, int alter);
    kunde(const kunde& orig);
    kunde(kunde&& orig);
    ...
    kunde& operator=(const kunde& rhs);
    kunde& operator=(kunde&& rhs);
    ...

private:
    string name;
    int alter;
    const int knr;
    ...
};

kunde::kunde(string name, int alter)
    : knr(MaxKnr++), name(name), alter(alter)
{
}

kunde::kunde(const kunde& orig)
    : knr(MaxKnr++), name(orig.name), alter(orig.alter)
{
}

kunde::kunde(kunde&& orig)
    : knr(MaxKnr++), name(std::move(orig.name)), alter(orig.alter)
{
}

kunde& kunde::operator=(const kunde& rhs)
{
    if (&rhs != this)
    {
        name = rhs.name;
        alter = rhs.alter;
        // CAN'T BE DONE, SO IGNORE IT
        // knr = rhs.knr;
    }
    return *this;
}

kunde& kunde::operator=(kunde&& rhs)
{
    name = std::move(rhs.name);
    alter = rhs.alter;
    // CAN'T BE DONE, SO IGNORE IT
    // knr = rhs.knr;
    return *this;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 2012-08-18
    • 1970-01-01
    • 2020-04-20
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多