您的位置:首页 > 财经 > 金融 > seo百度排名优化_阳江网络问政平台首页阳江政府网_常州百度推广代理公司_推广普通话黑板报

seo百度排名优化_阳江网络问政平台首页阳江政府网_常州百度推广代理公司_推广普通话黑板报

2024/12/22 15:33:56 来源:https://blog.csdn.net/weixin_71738303/article/details/142710558  浏览:    关键词:seo百度排名优化_阳江网络问政平台首页阳江政府网_常州百度推广代理公司_推广普通话黑板报
seo百度排名优化_阳江网络问政平台首页阳江政府网_常州百度推广代理公司_推广普通话黑板报

        c++对于数据成员给了你许多选项。除了在类中声明简单的数据成员,可以生成静态数据成员供所有类的对象共享,const成员,引用成员,reference-to-const成员,等等。本节我们解释一下这些不同类型的数据成员的细节。

1、静态数据成员

        有时候给类的第一个对象变量的拷贝会过度猎杀或者不管用。数据成员可能特定于类,但让每个对象有一个拷贝是不合适的。例如,你可能想给每个spreadsheet一个单独的数字标识符。就需要一个从0开始的计数器,每个对象可以包含它的ID。这个spreadsheet计数器确实属于Spreadsheet类,但是让每个Spreadsheet对象都有一个拷贝是没有什么道理的,因为不管怎么样你都要让所有的计数器同步。c++提供了一个解决方案,使用静态数据成员。静态数据成员是一个与类而不是对象相关联的数据成员。可以认为静态数据成员是类的全局变量。下面是Spreadsheet类的定义,包含了新的静态计数数据成员:

export class Spreadsheet
{// Omitted for brevityprivate:static std::size_t ms_counter;
};

        在类定义中除了列出静态类成员之外,还需要在源文件中为它们分配空间,通常会把类成员函数的定义放到源文件中。可以同时初始化它们,但是要记住与正常的变量与数据成员不同,它们缺省是被初始化为0的。静态指针会被初始化为nullptr。下面是分配空间并且将其初始化为0的ms_counter的代码:

size_t Spreadsheet::ms_counter;

        静态数据成员缺省初始化为0,但是如果你想,也可以显式地像下面这样对其进行初始化:

size_t Spreadsheet::ms_counter { 0 };

        该代码出现在任何函数或者成员函数体之外。差不多像是声明一个全局变量,除了Spreadsheet::范围解释符指出它是Spreadsheet类的一部分。

        与正常的数据成员一样,访问控制指示符也应用于静态数据成员。可以将ms_counter数据成员弄成public的,但是,你早已知晓,是不推荐拥有public数据成员的(我们后面要讨论的const static数据成员是个例外)。应该通过public的getter与setter来获得对数据成员的访问。如果想要给静态数据成员赋予访问的权限,可以提供public的静态get/set成员函数。

1.1、内联变量

        可以将静态数据成员声明为inline。这样做的好处是不需要在源文件中为其分配空间。下面是例子:

export class Spreadsheet
{// Omitted for brevityprivate:static inline std::size_t ms_counter { 0 };
};

        注意inline关键字,有了这样的类定义,下面这行代码就可以从源文件中移除了:

size_t Spreadsheet::ms_counter;

1.2、在类成员函数内访问静态数据成员

        可以使用静态数据成员就像它们是类成员函数中的通常的数据成员一样。例如,你可能会想生成一个Spreadsheet类的m_id的数据成员并在Spreadsheet构造函数中从ms_counter进行初始化。下面是带有m_id成员的Spreadsheet类定义:

export class Spreadsheet
{
public:// Omitted for brevitystd::size_t getId() const;
private:// Omitted for brevitystatic inline std::size_t ms_counter{ 0 }; std::size_t m_id { 0 };
};

        下面是对赋值给初始ID的Spreadsheet构造函数的实现:

Spreadsheet::Spreadsheet(size_t width, size_t height)
: m_id { ms_counter++ }, m_width { width }, m_height { height }
{// Omitted for brevity
}

        你可以看到,构造函数可以访问ms_counter就像它是一个正常的成员。拷贝构造函数也赋值一个新的ID。这会自动处理,因为Spreadsheet拷贝构造函数代理到non-copy构造函数,它生成了新的ID。

        对于这个例子,假定一旦ID赋值给一个对象,它就不再改变。所以,不应该在拷贝赋值操作符中拷贝ID。这样的话,推荐使m_id成为一个const数据成员:

export class Spreadsheet
{
private:// Omitted for brevityconst std::size_t m_id { 0 };
};

        既然数据成员一旦生成就不再改变,就不可能在构造函数体内初始化。这样的数据成员必须要么直接在类定义或者在构造函数初始化器中初始化。这也就意味着不能在赋值操作符中给这样的数据成员赋新值。对于m_id来说这不是总是,因为一旦Spreadsheet拥有了一个ID,它就不会再改变。然而,要依实际情况而定,如果这就使你的类无法赋值,赋值操作符就要被明正典刑--显式删除了。

2、constexpr静态数据成员

        类中的数据成员可以被声明为const或者constexpr,意思是它们在生成与初始化后不能被改变。应该使用static constexpr(或者constexpr static)数据成员在全局常量的位置上,当常量只应用于类时,也叫做类常量。整型的和枚举型的static constexpr数据成员可以被定义并且初始化在类定义内,即使没有将它们定义成内联变量。例如,你可能想要给spreadsheet指定一个最大的高度与宽度。如果用户想要构建一个比最大值更大的高度与宽度的spreadsheet,就会使用最大值。可以将Spreadsheet类的最大值高度与宽度弄成static constexpr成员。

export class Spreadsheet
{
public:// Omitted for brevitystatic constexpr std::size_t MaxHeight { 100 };static constexpr std::size_t MaxWidth { 100 };
};

        可以如下面这样在构造函数中使用新的常量:

Spreadsheet::Spreadsheet(size_t width, size_t height)
: m_id { ms_counter++ }
, m_width { std::min(width, MaxWidth) } // std::min() defined in <algorithm>
, m_height { std::min(height, MaxHeight) }
{// Omitted for brevity
}

        注意:不自动用最大值替换超过的宽度与高度,也可以决定在宽度与高度超过最大值时抛出例外。然而,在构造函数中抛出例外是不会调用析构函数的。所以要认真对待这一点。这个我们会在以后讨论错误处理时再详细讨论。

        这样的常量也可以用于参数的缺省值。记住只能对于从最右边开始的连续的参数给出缺省值。下面是例子:

export class Spreadsheet
{
public:explicit Spreadsheet(std::size_t width = MaxWidth, std::size_t height = MaxHeight);// Omitted for brevity
};

2.1、从类成员函数外部访问静态数据成员

如前所述,访问控制标识符应用于静态数据成员:MaxWidth与MaxHeight为public,所以它们可以从类成员函数外部访问,通过指定变量为Spreadsheet类的一部分,使用::范围解析操作符。例如:

println("Maximum height is: {}", Spreadsheet::MaxHeight);

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com