CPP设置子类的默认值

时间:2018-01-09 20:06:13

标签: c++ parent-child

您好我已经在学习CPP,并希望为儿童课程设置默认值,但我不知道要设置它,我尝试了很多东西而且没有在互联网上找到信息。我正在寻找尽可能少的施工人员。

我想在没有设置参数的情况下默认设置字符串arm by def0

class Parts {
    private:
        std::string _serial;
        bool _functionnal;
    public:
        Parts(std::string &serial, bool functional);
        std::string serial();
};

class Arms : public Parts {
    private:
        std::string _serial = "def0";
    public:
        Arms(std::string &serial, bool functionnal = true) : Parts(serial, functionnal)
        {
        }
};

Parts::Parts(std::string &serial, bool functional)
{
    this->_serial = serial;
    this->_functionnal = functional;
    std::cout << "Name set to: " << serial << std::endl;
}

int main()
{
    std::string sample = "sample";
    Arms Ex(sample, false);
    Arms setAsDefault();

    return 0;
}

2 个答案:

答案 0 :(得分:1)

您已经有了使用默认参数的基础,但是您缺少一个关键细节:您需要使string&成为const引用(否则您无法为其指定默认值)!

这要求您将Parts(声明和定义)的构造函数更改为:

Parts(const std::string &serial, bool functional)

Arms课程更改为:

class Arms : public Parts {
    public:
        Arms(const std::string &serial = "def0", bool functionnal = true) : Parts(serial, functionnal)
        {
        }
};

还有一个细节是Arms setAsDefault(); 创建一个新对象,而是声明一个返回Arms的函数(这被称为最令人烦恼的解析问题: https://en.wikipedia.org/wiki/Most_vexing_parse

相反,您需要将其更改为Arms setAsDefault;

编辑:实际上你可以使用member initializer lists来简化Parts的构造函数,这也会阻止默认的字符串构造(如user4581301所指出的),例如:

Parts::Parts(const std::string &serial, bool functional) : _serial(serial), _functionnal(functional)
{
    std::cout << "Name set to: " << serial << std::endl;
}

因此,您的示例更改为您想要的是以下代码

#include <string>
#include <iostream>

class Parts {
    private:
        std::string _serial;
        bool _functionnal;
    public:
        Parts(const std::string &serial, bool functional);
        std::string serial();
};

class Arms : public Parts {
    public:
        Arms(const std::string &serial = "def0", bool functionnal = true) : Parts(serial, functionnal)
        {
        }
};

Parts::Parts(const std::string &serial, bool functional) : _serial(serial), _functionnal(functional)
{
    std::cout << "Name set to: " << serial << std::endl;
}

int main()
{
    std::string sample = "sample";
    Arms Ex(sample, false);
    Arms setAsDefault;

    return 0;
}

为了使构造函数只占用bool(如注释中所述),您需要为构造函数提供另一个重载,例如: (使用C ++ 11委托构造函数):

Arms(bool functionnal) : Arms("def0", functionnal) {}

EDIT2:正如SergeyA所建议的那样,更好的选择是按值传递参数并使用std::move来移动构造成员变量。在这种情况下,您的类看起来像这样:

class Parts {
    private:
        std::string _serial;
        bool _functionnal;
    public:
        Parts(std::string serial, bool functional);
        std::string serial();
};

class Arms : public Parts {
    public:
        Arms(std::string serial = "def0", bool functionnal = true) : Parts(std::move(serial), functionnal)
        {
        }

        Arms(bool functionnal) : Arms("def0", functionnal) {}
};

Parts::Parts(std::string serial, bool functional) : _serial(std::move(serial)), _functionnal(functional)
{
    // Note that `serial` will be empty after the move
    // so you need to access the member variable instead
    std::cout << "Name set to: " << _serial << std::endl; 
}

答案 1 :(得分:0)

你可以这样:

class Parts {
    protected:
        std::string _serial;
    private :
        bool _functionnal;
    public:
        Parts(std::string &&serial, bool functional);
        std::string serial();
};

class Arms : public Parts {
    private:
        //std::string _serial = "def0"; this defines new variable which differs from parent's variable
    public:
        Arms(std::string &&serial="def0", bool functionnal = true) : Parts(serial, functionnal)
        {
        }
    };