公有成员函数是程序和对象的私有成员之间的桥梁,提供了对象和程序之间的接口。防止程序直接访问数据被称为数据隐藏。
类设计尽可能将公有接口与实现细节分开。将实现细节放在一起并将它们与抽象分开被称为封装。数据隐藏是一种封装,将实现的细节隐藏在私有部分中。封装的另一个例子是将类函数定义和类声明放在不同的文件中。
数据隐藏不仅可以防止直接访问数据,还让开发者无需了解数据是如何被表示的。
C++对结构体进行了扩展,使之具有与类相同的特征。唯一区别是,结构体的默认访问类型是public,而类为private。使用类实现类描述,结构体往往表示纯粹的数据对象。
其定义位于类声明中的函数都将自动成为内联函数,类声明常将短小的成员函数作为内联函数,例如set_tot()函数。
class Stock{
private:
long share;
double share_val;
double total_val;
void set_tot(){total_val=share*share_val;}
}
如果愿意,也可以在类声明之外定义成员函数,并使得其成为内联函数。为此,只需要在类实现部分中定义函数时使用inline限定符即可:,例子如下所示
class Stock{
private:
long share;
double share_val;
double total_val;
void set_tot();
}
inline void Stock::set_tot(){total_val=share*share_val;}
内联函数的特殊规则要求在每个使用它们的文件中都对其进行定义。确保内联定义对多文件程序中的所有文件都可用:将内联定义放在定义类的头文件中。
创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。
指定类设计的第一步是提供类声明。
第二步是实现类成员函数。
现在创建stack的构造函数。
stack(int co,long n);//构造函数声明
//构造函数定义
stack::stack(int co,long n){
...
}
有两种使用构造函数来初始化对象的方式。
第一种是显式地调用构造函数
stack food=stack(3,1.3);
另一种是隐式地调用构造函数
stack food(3,1.3);
上面两种方式等价
还有一种是与New一起使用
stack *food=new stack(3,1.3);
默认构造函数是在未提供现式初始值时,用来创建对象的构造函数。
stack fool;//使用默认构造函数
上面这句话的前提是,如果没有提供任何构造函数,则C++将自动提供默认构造函数。它是默认构造函数的隐式版本,不做任何工作。
当且仅当没有定义任何构造函数时,编译器才会提供默认构造函数。为类定义了构造函数后,程序员就必须为它提供默认构造函数。如果提供了非默认构造函数,但是没有提供默认构造函数,则下面的声明即将出错:
stack stk1;//不可能实现当前的构造
这样做的原因可能是想禁止创建未初始化的对象。
定义默认构造函数的方式有两种。一种是给已有构造函数的所有参数提供默认值:
stack(int co=0,long n=0);
另一种方式是通过函数重载来定义另一个构造函数——一个没有参数的构造函数:
stack();
只能有一个默认构造函数,因此不能同时采用这两种方式。
不要被非默认构造函数的隐式形式所误导:
stack stk(1,2);//调用非默认构造函数,
stack stk1();//stk1是一个返回stack对象的函数
stack stk2;//隐式调用默认构造函数。
C++11中,可以将列表初始化用于类,只要提供与某个构造函数的参数列表匹配的内容,并用大括号将它们括起:
Stock hot={"plus",100,&45.0};//
Stock jock{"age"};
Stock temp{};
//前面两个声明使用该构造函数来创建对象,第三个声明与默认构造函数匹配
Stock::Stock(const std::string &co,long n=0,double pr=0.0);
//
const Stock hot=Stock{"plus",100,&45.0};//
hot.show();
由于hot是const类型对象,因此show函数要保证调用对象不被修改——调用对象和const一样,不应该被修改。
因此show应该被声明为const成员函数:
void show() const;//声明方法
void Stock::show() const//定义
{
...
}
以下的枚举egg small和shirt small位于相同的作用域。它们将会发生冲突,编译器无法通过。
enum egg{small.large,jumbo};
enum shirt{small.large,Xlarge}
因此C++11提供一种新的枚举,其枚举量的作用域为类。实现方法如下,也可以用struct替代class。
enum class egg{small,large,jumbo};
enum class shirt{small,large,Xlarge};
使用方法
egg cho=egg::large;
shirt flo=shirt::large;
枚举量的作用域为类后。不同枚举定义中的枚举量就不会发生冲突了。