在没有提供构造函数的情况下以奇特的方式指定C ++对象属性

时间:2017-12-08 07:53:28

标签: c++ constructor c++14

考虑这个琐碎的课程:

#include <string>
class A
{
public:
    A( int i, const std::string& str ) : i(i), str(str)
    {
    }

    inline int getValue() const { return i; }
    inline std::string getName() const { return str; }

private:
    int i;
    std::string str;
};

int main()
{
    A a(3,"dkd");
    //...
    return 0;
}

在将新属性添加到类中时,必须维护构造函数是“一种痛苦”。好吧,不是那么痛苦,但是当构造函数如此明显时(它获取的属性与属性相同且参数顺序相同),最好不要声明任何,并且提供一个默认的干得好!

我想的是:

#include <string>
class A
{
public:
    inline int getValue() const { return i; }
    inline std::string getName() const { return str; }

private:
    int i;
    std::string str;
};


int main()
{
    A a{ 3, "ff" };
    ///...
    return 0;
}

这在C ++中是否可行?

2 个答案:

答案 0 :(得分:4)

不幸的是不适合你的情况。存在允许你这样做的东西,它被称为aggregate initialisation。它不能在您的示例中使用,因为它只能用于

的类
  • 没有私人/受保护的非静态成员
  • 没有构造函数
  • 没有virtual个功能

从链接本身:

  

聚合初始化是列表初始化的一种形式,它初始化聚合
  聚合是以下类型之一:
  *阵列类型
  *类型(通常是结构或联合),具有
  没有私人或受保护的非静态数据成员
  没有用户提供,继承或显式(自C ++ 17)构造函数(允许显式默认或删除构造函数)(自C ++ 11起)
  没有虚拟,私有或受保护(自C ++ 17)基类   没有虚拟成员功能
  没有默认成员初始值设定项

如果您的班级有public名成员,您将能够拥有以下内容:

class A
{
public:
    int i;
    std::string str;
};

int main()
{
    A a{ 3, "ff" };
}

如果您通过向其添加新成员来扩展课程,则无需更新旧代码。未包含在初始化列表中的成员是默认初始化的:

  

如果初始化程序子句的数量小于成员数或初始化程序列表完全为空,则其余成员将进行值初始化。

class A
{
public:
    int i;
    std::string str;
    double d;
};

int main()
{
    A a{ 3, "ff" }; // your old code still works, a.d becomes 0.0
    A b{ 3, "ff", 1.0 };
    A c{}; // 0, "", 0.0
}

答案 1 :(得分:1)

了解http://en.cppreference.com/w/cpp/language/aggregate_initialization, 您的代码将不会被编译,因为您的班级成员将被私有。

如果您的班级成员是公开的,您的代码就可以使用。