c++类的特性探究(一)

原创 2015年10月04日 18:24:16

类的定义可以使用struct关键字或者class关键字,两者唯一的区别就是默认的访问权限。访问权限与类的访问控制说明符有关:

public:定义在public后面的成员可以在整个程序里面被访问

private:定义在private后面的成员只能在类内部被访问

struct Sales_data{
public:

//public成员,可在整个程序里面被访问
    //构造函数,用于创建对象时初始化数据成员
    Sales_data()=default;
    Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
    Sales_data(const string &s):bookNo(s){}
    Sales_data(istream&);
    //成员函数:关于sales_data对象的操作
    string isbn() const {return bookNo;}
    Sales_data & combine(const Sales_data&);
private:

//private成员,仅可在类内部被访问
    double avg_price()const{return units_sold?revenue/units_sold:0;};
    //数据成员:属于sales_data对象的属性
    string bookNo;
    unsigned units_sold=0;
    double revenue=0.0;
};

注:有些类成员可能定义在第一个说明符之外,那么此时如果使用struct关键字定义类,这些成员是public的,如果使用class关键字定义类,这些成员是private的。


友元:为了使得类的非成员接口函数能够访问类中的成员(包括公有私有),c++中引入友元一词,用以表示可以访问类的私有成员的友情函数。友元声明只能再类的内部,一般在顶部或者尾部,在函数前面加上friend关键字:

struct Sales_data{
friend Sales_data add(const Sales_data&,const Sales_data&);
friend ostream &print(ostream&,const Sales_data);
friend istream & read(istream&,Sales_data&);

public:
    //构造函数,用于创建对象时初始化数据成员
    Sales_data()=default;
    Sales_data(const string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
    Sales_data(const string &s):bookNo(s){}
    Sales_data(istream&);


    //成员函数:关于sales_data对象的操作
    string isbn() const {return bookNo;}
    Sales_data & combine(const Sales_data&);
private:
    double avg_price()const{return units_sold?revenue/units_sold:0;};
    //数据成员:属于sales_data对象的属性
    string bookNo;
    unsigned units_sold=0;
    double revenue=0.0;
};

//这三个即为友元
Sales_data add(const Sales_data&,const Sales_data&);
ostream &print(ostream&,const Sales_data);
istream & read(istream&,Sales_data&);

友元函数虽然已经在类内部有过一次声明,但是在类的外部还需一次声明,通常将类的声明和友元函数的声明放在同一个头文件。

友元函数也可以直接在类内部定义,但是还是需要在类的外部再次进行声明以使得友元函数可见。

除了可以声明友元函数外,还可以声明友元类以及某一个类中的部分成员函数为友元函数。

class screen{

friend class WindowMgr;//声明class WindowMgr是class screen的友元类,class WindowMgr的成员函数可以访问class screen的非公有成员

friend void window_mgr::clear(int);//声明window_mgr的成员函数clear为screen的友元函数,可以访问screen的非公有成员。

}

如果要将某个类的成员函数作为一个类的友元,我们需要严格的组织程序结构,以window_mg的clear函数作为screen的友元为例:

1.首先定义window_mgr类,其中声明clear函数,但是不能定义它,因为它将要用到的screen还没有声明。

2.定义screen类,包括对于window_mgr的clear函数的友元声明

3.定义clear函数,此时可以使用screen。



友情小贴士:封装的益处

1.确保用户代码不会无意间破坏封装对象的状态

2.类的具体实现细节可以随时改变,而不用调整用户级代码


类的可变数据成员:

有时候我们希望只改变对象的某一个数据成员(即便这个对象是const对象),此时可以在数据成员的声明里面加入关键字mutable。

class Screen{
public:
    void some_member()const;//改变可变数据成员access_ctr,统计成员函数被访问次数
private:
    mutable size_t access_ctr=0;//可变数据成员
};
void Screen::some_member()const{
    ++access_ctr;
}


关于返回*this的成员函数

有些成员函数需要返回调用对象以进行下一步操作,此时成员函数应该返回对于调用对象的引用,这样才可保证所有的操作都是作用在调用对象上面。例如:

myScreen.move(4,0).set('#');//移动光标同时设定光标显示的字符

此时如果move函数返回对象的引用,那么紧随其后的set函数也是作用在myScreen上面;如果move函数返回对象,那么set函数将会作用在所返回的对象副本上,与myScreen无关。对于返回常量非常量引用可以使用函数重载的方法解决。对于函数体中对于常量对象和非常亮对象不同的操作可以将不同功能的代码独立成一个成员函数,由于类中的成员函数都是内联函数,所以不会带来函数调用的额外开销。


类的作用域:

当我们要使用类中的成员时,我们必须在这之前使用类名和作用运算符指定具体的类。在类的外部定义成员函数时,一般函数名前面会有类名,因此函数体和参数列表都可以使用类的成员,但是函数的返回类型是在函数名之前的,如果函数返回值类型需要用到类中的成员,那么必须也要使用作用域运算符指定具体的类,即便使用的是同一个类。

编译器处理类定义的两个阶段:

1.首先编译全体成员的声明(包括成员函数)

2.直到类全部可见之后才编译函数体(函数声明中返回类型、参数列表所用到的名字必须在声明以前已经出现过)

成员函数的块中使用符号时的名字查找规则:

1.首先在函数内部查找该名字

2.如果函数内部没有其定义或者声明,那么在类中查找该名字(成员函数之前或者之后出现的都可以,只要在类中声明)

3.如果在类中仍然未找到该名字,那么在类外的全局作用域中寻找该名字(必须在使用该名字之前有过定义)

注:类型别名比较特殊,类的内部不允许覆盖外部的类型别名。并且即便是在类内部,定义类型别名也必须先定义后使用

综合上述规则可理清楚程序中有关符号作用域的问题

C++中类的继承访问特性

原文:http://blog.csdn.net/shandiantianying/article/details/9446407 一个私有的或保护的派生类不是子类,因为非公共的派生类不能做基类能做的...
  • gongda2014306
  • gongda2014306
  • 2016-11-15 17:08:13
  • 674

C++五大特性

1.对象    在客观世界里,任何一个事物都可以看做一个对象(object),或者说我们的世界是由无数个对象组成的。对象可以是自然的物体,如天安号、诺亚方舟等,也可以是一些逻辑结构,如联合国、C++...
  • MissLong
  • MissLong
  • 2014-01-20 16:45:06
  • 5996

C++ ——三大特性理解

1.封装 突破了C语言函数的概念,封装可以隐藏实现细节,使得代码模块化。2.继承 继承可以扩展已存在的代码模块(类);达到代码重用的目的。要实现继承,可以通过“继承”(Inheri...
  • michael019
  • michael019
  • 2015-10-01 10:03:02
  • 2818

C++ 动态特性小结

之前学C++动态特性,主要是父类指针指向子类对象这个使用方法比较复杂,这也是C++的精髓之一,下面从内存结构方面对此用法解析一下 内存空间结构图如下所示            code sa...
  • dannygaobo
  • dannygaobo
  • 2015-08-06 16:54:02
  • 365

理解C++三大特性

封装,继承,多态      封装可以隐藏实现细节,使得代码模块化,继承可以扩展已存在的模块,它们目的都是为了:代码重用。而多态是为了实现另一个目的:接口重用。 什么是多态?   ...
  • Doo66
  • Doo66
  • 2016-08-15 10:26:16
  • 7500

C++三大特性之多态

1、什么是运行期多态? 在程序执行期间(非编译期)判断所引用对象的实际类型,根据其实际类型调用相应的方法。使用virtual关键字修饰类的成员函数时,指明该函数为虚函数,派生类需要重新实现,编译器将...
  • hj605635529
  • hj605635529
  • 2016-11-13 23:05:15
  • 460

C++四大特性——多态 的总结

我们都知道,C语言和C++的区别就是,C语言是面对过程的程序设计,而C++是面对对象的程序设计。面对对象的程序设计有4大特性:分别是,抽象、封装、继承、多态。今天我们就来总结一下多态的内容。多态:分为...
  • jhcconan614
  • jhcconan614
  • 2017-03-11 15:26:49
  • 2109

C++的三个基本特征

向对象的三个基本特征是:封装、继承、多态。 封装 封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己...
  • kakaka2011
  • kakaka2011
  • 2013-07-02 10:58:06
  • 1153

线程安全与并发编程探究(七)--volatile java内存模型及线程知识小结

一、volatile与java内存模型 当一个变量定义为volatile之后,可以保证此共享变量对所有其他线程的可见性,即一条线程修改了该变量的值,则新值对于其他线程来说都是可以立即得知的立即可见的...
  • dongping1023
  • dongping1023
  • 2015-08-06 16:10:27
  • 339

一步一步学习C++(类)之成员函数的特性

在类体中说明的函数作为类的成员,称为成员函数。一般的成员函数,它是根据某种类的功能的需要来定义的。除此之外,又讨论了一些特殊的成员函数:构造函数、析构函数、拷贝初始化构造函数等。本节讨论除成员函数定义...
  • xy010902100449
  • xy010902100449
  • 2015-04-09 11:29:40
  • 715
收藏助手
不良信息举报
您举报文章:c++类的特性探究(一)
举报原因:
原因补充:

(最多只允许输入30个字)