类声明
//类是一种用户自定义类型,声明形式:
class 类名称
{
public:
公有成员(外部接口)
private:
私有成员
protected:
保护成员
};
共有、私有、保护成员
- 在关键字public后面声明,它们是类与外部的接口,任何外部函数都可以访问公有类型数据和函数。
- 在关键字private后面声明,只允许本类中的函数访问,而类外部的任何函数都不能访问。
- 在关键字protected后面声明,与private类似,其差别表现在继承与派生时对派生类的影响不同。
数据抽象和封装
- 数据抽象是一种依赖于接口和实现分离的编程(和设计)技术。类设计者必须关心类是如何实现的,但使用该类的程序员不必了解这些细节。使用者只要抽象地考虑该类型做什么,而不必具体地考虑该类如何工作。
类的使用者不需要关注内部是怎么实现,也不需要关注内部所采用的数据,它只需要关注这个类能提供什么功能,只要这个类所提供的功能不变,也就是类所提供的功能不变,也就是类所暴露的接口不必那稳定。那么对类使用者所编写的代码就是稳定的。 - 封装是一项将低层次的元素组合起来形成新的、高层次的实体的技术。函数是封装的一种形式:函数所执行的细节行为被封装在函数这个更大的实体中。被封装的元素隐藏了它们的实现细节——可以调用函数,但是不能直接访问函数所执行的语句。同样地,类也是一个封装的实体:它代表若干成员的聚集,设计良好的类隐藏了类实现的细节。
内联成员函数
内联函数可以提高效率,因为在编译的时候将代码直接嵌入到调用的地方,从而减少了函数调用的开销。体积增大,以空间换时间。内联函数仅仅只是给编译器一个提示,如果函数中有switch,for,可能就不会被解析。
成员函数的重载及其缺省参数
相同的作用域,函数名相同,参数可能不同,缺省参数是指函数参数已经有初始值。
类与结构体
- class与struct的区别:在未指定访问权限时,class默认的是私有的,struct默认是共有的。
struct s
{
int x;//公有的
...
}
class C
{
int X;//私有的
...
}
隐含的this指针
- 成员函数有一个隐含的附加形参,即指向该对象的指针,这个隐含的形参叫做this指针。
- 使用this指针保证了每个对象可以拥有不同的数据成员,但处理这些成员的代码可以被所有对象共享。
类作用域
- 每个类都定义了自己的作用域称为类作用域
- 类作用域中说明的标识符只在类中可见
- 1、块作用域
- 2、文件作用域
- 3、函数原型作用域
- 4、函数作用域
- 5、类作用域
#include <iostream>
using namespace std;
class Test
{
public:
int num_;
};
//num_=20 Error,num_的作用域在类内部
int num_=20;//num_的作用域是文件作用域,与类中的num_是不同的作用域
int add(inta, int b);//a,b两个表示符的作用域为函数原型作用域
int main()
{
int num_ = 30//num_为块作用域
{
int num_ = 100; //num_为块作用域
}
cout<<num_<<endl; // 输出30
cout<<::num_<<endl;//输出20
return 0;
}
int add(int a,int b)//形参a,b也算块作用域
{
return a+b;
}
int test()
{
Label1:
cout<<"label1"<<endl;
goto Label3;//函数作用域
Label2:
cout<<"label2"<<endl;
goto Label1;
Label3:
cout<<"label3"<<endl;
goto Label2;
}
前向声明
- C++中类必须先定义,才能够实例化
- 两个类需要相互引用形成一个"环形"引用时,无法先定义使用。这时候需要用到前向声明
- 前向声明的类不能实例化
嵌套类
- 外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用于外围类的实现,且同时可以对用户隐藏该底层实现。
#include <iostream>
using namespace std;
class Outer
{
class Inter
{
public:
void fun()
{
cout << "Inner::Fun..."<<endl;
};
};
public:
Inner obj_;
void Fun()
{
cout<<"Outer::Fun..."<<endl;
obj_ fun();
}
};
int main()
{
Outer o;
o.Fun();
return 0;
}
- 从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类的作用域使用该类名时,需要加名字限定。
- 嵌套类中的成员函数可以在它的类体外定义。
- 嵌套类的成员函数对外围类的成员没有访问权,反之亦然。
- 嵌套类仅仅只是语法上的嵌入
#include <iostream>
using namespace std;
class Outer
{
class Inter
{
public:
void fun();
//{
// cout << "Inner::Fun..."<<endl;
//};
};
public:
Inner obj_;
void Fun()
{
cout<<"Outer::Fun..."<<endl;
obj_ fun();
}
};
void Outer::Innner::fun()
{
cout << "Inner::Fun..."<<endl;
}
int main()
{
Outer o;
o.Fun();
return 0;
}
局部类
- 类也可以定义在函数体内,这样的类被称为局部类(loacl class)。局部类只在定义它的局部域内可见
- 局部类的成员函数必须被定义在类体中。
- 局部类中不能有静态成员