C++11基础语法知识总结(二)

1、类的const相关特性

1.1、 this指针

每个类的对象都有一个this指针,this指针是一个指向类对象的const指针,因此,这个const是一个顶层const

1.2、const成员函数

std::string isbn() const{return boolN};

这里的const作用是修改隐式this指针的类型,使得this变成指向常量的常量指针,这个const是一个底层const

1.3、常量对象

常量对象的引用或指针都只能调用常量成员函数。如果一个const成员函数以引用的形式返回*this,那它的返回类型必须是常量引用,而且返回值(即this指针)无法调用类中的非常量函数。

2、类的构造函数

2.1、 默认构造函数

特点:无任何实参,采用默认值进行对象的初始化的构造函数。调用默认构造函数进行初始化时,要去掉对象名后的空括号对:

Sales_data obj; **//obj是一个默认初始化的对象**
Sales_data obj(); **//这是声明一个函数,而非对象**

某些类不能依赖合成的默认构造函数,原因:
1、编译器只有在发现类不包含任何构造函数的情况下才会生成默认构造函数,一旦定义了其他构造函数,除非再定义一个默认构造函数,否则类没有默认构造函数。
2、对于某些类来说,合成的默认构造函数可能执行错误的操作。因此,如果类包含有内置类型或者复合类型的成员,只有当这些成员全部被赋予了类内的初始值,这个类才适合于使用合成的默认构造函数
3、有时候编译器不能为某些没有默认构造函数的类合成默认构造函数
=default,指定默认构造函数。如果=default在类的内部,则默认构造函数是内联的;在类的外部,则不是内联的。

2.2、构造函数初始值

当定义一个变量是应立即对其进行初始化,而非先定义、再赋值

	string foo = "hello";//定义并初始化
	
	string bar;  //默认初始化为空
	bar = "hello";//赋值

如果类的成员是const、引用,或者属于某种未提供默认构造函数的类类型,则必须通过构造函数初始值列表为这些成员提供初值

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

以下这种构造函数是不对的。在构造函数体一开始执行时,初始化就完成了,构造函数体内的操作是在初始化后进行赋值。而常量对象和引用必须提供初始值,否则就会报错。

ConstRef::ConstRef(int ii)
{
//赋值
	i == ii;
	ci = ii;
	ri = i;
}

必须通过初始值列表就可以正确地给const、引用提供初始值

ConstRef::ConstRef(int ii) :i(ii),ci(ii), ri(ii){}

2.3、默认实参与构造函数

如果一个构造函数为所有的参数都提供了默认实参,则它实际上也定义了默认构造函数,我们可以像调用默认构造函数一样调用它。

2.4、类类型的隐式转换

string s3 = "string"; **//拷贝初始化,char*隐式转化为string对象,再拷贝s3。**

在上述例子中,=右侧运算对象为const char*,这里存在一个隐式转换,const char*先被隐式转换为string对象,再拷贝s3。

2.4.1、类类型隐式转换规则:

1、如果构造函数只接受一个实参,或者除了一个形参以外的其他所有形参都有默认值。这样就定义了一个从构造函数参数类型向类类型隐式转换的规则。
2、编译器只会执行一次类类型隐式类型转换,如果在构造函数中涉及到多次的类类型转换,则会报错。

class Screen
{
public:
	Screen(const string& b):a(b){}
	string a;
};
Screen sc = s4;  **//正确,单步隐式类型转换**
	Screen sc = "string";**//错误,无法从const char*多步隐式转化为Screen对象**
2.4.2、如何抑制构造函数的隐式转换

通过在构造函数前加explicit关键字,则这个构造函数不会进行隐式转换。比如将string的构造函数string(const char*);改成explicit string(const char*);则上述例子就会报错。因为上述例子存在隐式类型转换,原本右侧的cinst char会隐式调用string的构造函数string(const char),当声明为explicit后,编译器会跳过这个构造函数,从而导致构造失败。

class Screen
{
public:
	explicit Screen(const string& b):a(b){}
	string a;
};
Screen sc = s4;  **//错误,不接受隐式类型转换**
Screen sc1 = Screen(s4);**//正确,拷贝初始化,但不存在隐式转换**

因此,用explicit关键字声明的构造函数只能以直接初始化的形式使用,不能用于存在隐式转换的拷贝初始化。

2.5、聚合类

聚合类满足以下条件:
1、所有成员都是public的
2、没有定义任何构造函数
3、没有类内初始值
4、没有基类,也没有virtual函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值