c++Primer——第七章:类(基础,后面还会讲到)

1、构造函数

只有当类没有声明任何构造函数时,编译器才会自动地生成默认构造函数。但有时候编译器不能为类合成默认构造函数,例如类中包含一个其他类类型的成员且这个成员没有默认构造函数,那么编译器将无法初始化该成员。当然还有一些其他情况,将在13章中介绍。

c++11中可以通过在参数列表后写上 =default;来让编译器生成构造函数。

2、struct和class的唯一区别是默认的访问权限,前者默认public,后者默认private。

3、可变数据成员

通过在变量的声明中加入mutable关键字可以使这个变量能被修改,即使是在一个const成员函数内。

class A
{
public:
	void fun()const;
private:
	mutable int a;
};

void A::fun()const
{
	++a; //合法 虽然fun是个const函数  但是a是个mutable变量
}

4、友元

每个类负责控制自己的友元类或友元函数,友元关系不存在传递性。

5、类的作用域

在类的外部定义成员函数时,函数返回值类型和函数名都不在类的作用域内

class A
{
	typedef int index;
	index getidx();
};

index A::getidx()			//错误  index未定义  应该用A::index
{
	return 1;
}

一般来说内层作用域可以重新定义外层作用域中的名字,即使改名字已经在内层作用域总使用过,然而在类中,如果成员使用了外层作用域中的某个名字,而改名字代表一种类型,则类不能在之后重新定义改名字(有些编译器可以通过):

typedef double Money;
class A
{
public:

	Money fun() { return bal; }			//使用外层作用域的Money
private:
	typedef int Money;					//书上说这里是错误的 重定义了 在linux上g++编译的确报错了  但是vs上是可以的
	Money bal{5};
};

6、构造函数初始值列表

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

初始值列表初始化成员的顺序与成员在类中定义的顺序一致,而与它在初始值列表中出现的位置无关。

7、隐式的类类型转换

只允许一步的类类型转换。编译器只会自动地执行一步类型转换

class A
{
public:
	A() {};
	A(string& str) :a(0), s(str) {};
	void aprint(const A& ra) { cout << ra.s << endl; }
	int a;
	string s;
};

void test()
{
	A a;
	string str = "aaaa";
	a.aprint("aaaa"); //错误  aaaa->string是一步转换  string到A是一步转换
	a.aprint(str);		//正确
	a.aprint(string("aaaa")); //错误  按照书上说的应该可以  但是编译失败  不知道为什么
	a.aprint(A("aaaa")); //错误  按照书上说的应该可以  但是编译失败  不知道为什么
}

8、explicit

构造函数声明前加explicit可以阻止隐式转换,explicit只允许出现在类内的构造函数声明处。

当用explicit关键字声明构造函数时,它将只能以直接初始化的形式使用,不能将explicit用于拷贝形式的初始化过程,而且编译器不会在自动转换过程中使用该构造函数。

9、constexpr关键字

10、类的静态成员

    1)静态成员函数不与任何对象绑定在一起,他们不包含this指针,作为结果,静态成员函数不能声明成const的。

        对于为什么静态成员函数不能声明为const,我是这么理解的:它不含this指针是前提,普通成员函数的const意思是不能修改它的普通成员变量,其实是把const作用到了this指针身上。而静态成员函数是不知道归属于对象的普通成员变量的,更谈不上去修改它,所以即使有const也没意义,其实关键在于const是作用到this指针的,静态成员函数没有this指针。

        突然有个想法,const是作用与this指针的,而静态成员变量不属于某个对象,那const的成员函数是否能修改静态成员变量呢?

class A
{
public:
	A() {};
	void fun() const;
	static int a;
	int b{ 10 };
};
int A::a = 5;

void A::fun()const
{
	a++;
	//b++;   b是对象的成员  由于const的限制不能修改
	cout << a << " " << b << endl;
}

void test()
{
	A a;
	cout << a.a << " " << a.b << endl;
	a.fun();
}

        事实证明是可以的,cosnt成员函数是可以修改可变(mutable)或静态(static)成员

        2)静态成员能用于某些场景,而普通成员不行

class Bar
{
public:
	// ...
private:
	static Bar mem1;		//正确 静态成员可以是不完全类型  不完全是指  这里的Bar还只有声明没有定义
	Bar*	   mem2;		//正确 指针和引用成员可以是不完全类型
	Bar		   mem3;		//错误 数据成员必须是完全类型
};

        3)静态成员可以作为默认实参,普通成员不行

class Bar
{
public:
	// a表示一个在类中稍后定义的静态成员
	Bar& fun(int b = a);
private:
	static const int a;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值