首页 > 编程语言 >C++构造函数、隐式的类类型转换、类的静态成员---C++ primer 7.5 7.6笔记

C++构造函数、隐式的类类型转换、类的静态成员---C++ primer 7.5 7.6笔记

时间:2022-11-06 17:45:34浏览次数:47  
标签:类型转换 初始化 string int 成员 Sales C++ 构造函数

7.5构造函数再探

构造函数初始化列表

const和引用必须进行初始化,而不能在构造函数中赋值。

class ConstRef {
    public:
        ConstRef(int ii);
    private:
        int i;
        const int ci;
        int &ri;
};

ConstRef::ConstRef(int ii)
{
    i = ii;
    ci = ii; //错误:不能给const赋值
    ri = i;  //错误:ri没被初始化
}

//正确的做法
ConstRef::ConstRef(int ii):i(ii),ci(ii),ri(i){ }

养成使用构造函数初始值列表的习惯。


成员初始化顺序

成员初始化的顺序和它们在类中定义中出现的顺序一致。
最好令构造函数的初始值列表顺序与成员声明的顺序保持一致,尽量避免使用某些成员初始化其他成员,最好直接使用构造函数的参数。

class X{
    int i;
    int j;
public:
    x(int val): j(val), i(j){ }
}

默认实参

如果一个构造函数为所有参数都提供了默认实参,则它实际上也定义了默认的构造函数。

class Sales {
    Sales(std::string s = ""): bookNo(s){ }
};

委托构造函数

C++11标准
委托构造函数使用所属类的其他构造函数执行自己的初始化过程。
当一个构造函数委托另一个构造函数时,受委托的构造函数的初始值列表和函数体依次被执行,然后才执行委托者的函数体。

class Sales {
public:
    Sales(std::string, unsigned cnt, double price):
    bookNo(s), units_sold(cnt), revenue(cnt*price) { }
    Sales():Sales("", 0, 0){ } //使用了委托构造函数
    Sales(std::string s):Sales(s, 0, 0){ }
private:
    std::string bookNo;
    unsigned units_sold;
    double revenue;
};

隐式的类类型转换

如果一个构造函数只接受一个实参,则他实际上定义了转换为此类类型的隐式转换机制。

string book = "ssss";
item.combine(book); //combine的参数是Sales类型,自动调用了Sales只接受string类型的构造函数,创建了一个临时的Sales对象。

但是注意:只接受一步类型转换。

可以把构造函数声明为explicit来阻止隐式的类型转换

class Sales {
public:
    Sales(std::string, unsigned cnt, double price):
    bookNo(s), units_sold(cnt), revenue(cnt*price) { }
    explicit Sales():Sales("", 0, 0){ } //使用了委托构造函数
    explicit Sales(std::string s):Sales(s, 0, 0){ }
private:
    std::string bookNo;
    unsigned units_sold;
    double revenue;
};
string book = "ssss";
item.combine(book); //报错,构造函数是explicit

直接初始化:
null_book = "AAA"
Sales item1(null_book)

拷贝初始化:
Sales item1 = null_book;

explicit构造函数只能用于直接初始化。


聚合类

当一个类满足以下条件时,是一个聚合类:

  1. 所有的成员都是public
  2. 没有定义任何的构造函数
  3. 没有类内初始值
  4. 没有基类,没有virtual函数

比如:

struct Data{
    int ival;
    string s;
}

我们可以提供一个花括号括起来的成员初始化列表来初始化聚合类的数据成员。
Data vall = { 0, "Anna"};
初始值顺序和声明顺序必须一致。
如果初始值列表的元素个数少于类的成员数量,那么靠后的成员使用默认值。

显示的初始化聚合类的对象的缺点:

  1. 添加或者删除一个成员之后,所有的初始化语句都要更新。
  2. 将正确的初始化对象的任务交给了用户,没有提供初始值。

7.6类的静态成员

有时候类需要一些成员和类本身直接相关。
类的静态成员存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据。
同样,静态成员函数体内,不包含this指针。静态成员函数不能被声明为const.

使用类的静态成员:

使用作用域直接访问静态成员。
使用类的对象,引用和指针访问。

class Account{
public:
    static double rate(){ return interestRate;}
    static void get();
private:
    static double interestRate;
};

int main(){
    double r;
    r = Account::rate();
    Account ac1;
    Account *ac2 = &ac1;
    r = ac1.rate();
    r = ac2->rate();
}

void Account::get(double new) //类外部定义
{
    interestRate = new;
}

定义静态函数:

在类的外部定义静态数据成员时,不能重复static关键字,该关键字只出现在类的内部
生命周期类似全局变量,一旦被定义,就一直存在于程序的整个生命周期中。
可以使用类的私有成员来定义静态成员变量。

作用场景:
我们可以使用静态成员作为默认实参。非静态数据成员不能作为默认实参。

标签:类型转换,初始化,string,int,成员,Sales,C++,构造函数
From: https://www.cnblogs.com/hy227/p/16863155.html

相关文章

  • C/C++ 数组、指针与函数
    数组与指针数组名数组第一个元素的地址intar[10];int*p=ar;p==&ar[0];*p==ar[0];多维数组可看做一维数组,其每个元素也是一个数组intar[4][5];int(*......
  • C++图书馆管理系统
    C++图书馆管理系统程序设计题六:图书馆管理系统1问题描述该系统要求建立一个图书馆管理系统,并具有排序、查找、计算、显示等功能。通过此课题,熟练掌握文件、数组、指针......
  • java基本数据类型转换规则
    数据类型的转换是保证数据精确度的一种手段。2个基本事实自动转化强制转化编译器的优化2个基本事实事实-**浮点数常量默认为double**floata=3.5;//此处将会由d......
  • C/C++中的枚举数据类型
    关键字:Emum自定义名称{a=1b=2,c=3,d=4}box;定义好之后可以直接通过box关键字调用ennumbag{book1="百年孤独",book2="时间简史",book3="简爱"}boo......
  • C/C++表达式求值(带括号)
    C/C++表达式求值(带括号)实验内容及要求(功能)1.友好的用户界面,给出简单用户帮助2.通过键盘输入表达式(负数,小数),表达式可包含加(+)、减(-)、乘(*)、除(/)、求模(%)、开......
  • C++ Balanced Braces
    C++BalancedBracesAstringofcharactershasbalancedbraces(parentheses,curlybraces,andsquarebraces)ifeachright-facingbraceoccurringinthestrin......
  • Effective C++ - 条款17 - 总是以独立语句将new对象放入到智能指针中
    这个条款所说的意思就是,不要把new对象并放入智能指针这个操作放入到一个别的过程之中。例如,如果把new对象并放入智能指针放入到一个传参过程之中,可能会发生其他参数的执行......
  • Effective C++ - 条款16 - new和delete使用相同的形式
    不要对数组做typedef,会产生很多问题,尽量使用std的string和vector来代替。new和new一个数组时,内存实际布局有区别,new数组时,会在开头记录数组长度(具体编译器有不同实现,但......
  • 解决Dev-C++中文注释无法显示,单击才能显示的问题
    解决Dev-C++中文注释无法显示,单击才能显示的问题_任青月的博客-CSDN博客......
  • 周六1900C++班级2022-11-5 双重for循环
    4872:#include<bits/stdc++.h>#include<iostream>//C++#include<cstdio>//有这个才能使用printfusingnamespacestd;intmain(){//4872//定义输入n,x......