C++ Primer 类 12.1-12.2 this ,定义

原创 2016年05月30日 14:59:04

12.1 类的定义和声明

类由类成员组成。类成员包括属性,字段,成员函数,构造函数,析构函数等组成。 

类设计应该遵从抽象封装性。

类抽象性指对于类的使用者来说只需知道类接口即可使用类功能。类的具体实现由设计者负责。即使某个功能发生了变更但由于使用者是以接口方式调用类所以用户代码无需做任何修改。

类封装性指类用户只需知道类的功能无需了解具体实现。实现代码对用户来说不可见。 

C++类没有访问级别限限制,定义类时不能用public 或 private 做修饰。类成员有访问级别,可以定义 public protect private

#include<iostream>

using namespace std;

 

class Screen

{

            public:

                         //类成员只能声明不允许定义 替换成stringname("tom")

                        //会产生编译错误, 数据成员初始化工作在构造函数中执行

                        string  name;           

 

                        // 给类定义别名类型成员 index 由于别名要在外部访问所

                        //以一定要定义在 public

                        typedefstd::string::size_type index;

 

                        //构造函数

                        Screen( index cur =100);

 

                        //析构函数

                        ~Screen();

 

                        // 内部定义的函数,等价于inline

                        char get() const {return contents[cursor]; }

 

                        // 内部声明一个成员函数(无定义),且函数是内联的inline

                        //表示在编译时该声明会被替换成定义语句

                        inline char get(indexht, index wd) const;

 

                        // 内部声明一个成员函数(无定义)

                        index get_cursor()const;

 

            private:

                        std::string contents;

                        index cursor;

                        index height,width;

};

 




#include<iostream>

#include"def_class.h"

using namespace std;

 

inline Screen::Screen(Screen::indexcur ){

            cursor = cur;

            width = 20;

            height = 10;

}

 

inlineScreen::~Screen(){

 

}

 

// 定义类 Screen 的成员函数get 具体实现

charScreen::get(index r, index c) const

{

 

            index row = r * width;    // compute the row location

 

            return contents[row + c]; // offsetby c to fetch specified character

 

}

 

 

// 定义类 Screen 的成员函数get_cursor 具体实现,且是内联的

 

inline Screen::indexScreen::get_cursor() const

//inline indexScreen::get_cursor() const

{

 

            return cursor;

 

}

 

#include<iostream>

#include"def_class.h"

 

using namespace std;

 

int main( int argc ,char *argv[] ){

            Screen wnd;

            size_t cur;

 

            /* operate member function */

            cur = wnd.get_cursor();

            cout<<cur<<endl;

 

            return 0;

}


注:1.类的inline修饰符可以放在类内部申明也可以放在外部定义。一般放在内部声明便于理解。

类定义完毕后一定要加上封号结束符;。

类数据成员只允许声明不允许定义;

2.编译的时候应该这样

g++ -fkeep-inline-functions main.cpp def_class.cpp

分析原因,由于def_class.h所有函数在实现文件def_class.cpp中均显式声明为内联,根据g++编译的默认选项是-fno-keep-inline-functions,如果函数被内联,则不存在对函数的调用,编译程序将不生成函数体,因此虽然main.cpp中include了相关函数的定义,但是找不到这些函数的实现,自然出现错误"undefinedreference toXXX"。 
修改该选项为-fkeep-inline-functions,则及时不存在对函数的调用,编译程序也会生成函数体,于是世界又清静了。



12.2 this指针

1.这些函数的返回类型是 Screen&,指明该成员函数返回对其自身类类型的对象的引用。

2.在普通的非 const 成员函数中,this 的类型是一个指向类类型的 const 指针。可以改变 this 所指向的值,但不能改变 this 所保存的地址。

3.基于成员函数是否为 const,可以重载一个成员函数;同样地,基于一个指针形参是否指向 const( 7.8.4),可以重载一个函数。const 对象只能使用 const成员。非 const 对象可以使用任一成员,但非 const 版本是一个更好的匹配。

4. 类对象包含一个 this 指针指向自身(当前的实例对象)且无法更改指针指向。在普通的非 const 成员函数中,this 的类型是一个指向类类型的 const 指针。可以改变 this 所指向的值,但不能改变 this 所保存的地址。在 const 成员函数中,this 的类型是一个指向 const 类类型对象的 const 指针。既不能改变 this 所指向的对象,也不能改变 this 所保存的地址。

    基于成员函数是否为 const,可以重载一个成员函数;同样地,基于一个指针形参是否指向 const可以重载一个函数。

class mycls

{

    public:

        mycls(){}; // 想要定义 const mycls a; 必须要显示定义默认构造函数

        mycls &Get(){ return *this; };

        const mycls &Get() const { return*this; }; // 想如果const函数返回this引用或指针; 必须要返回const指针或引用,因为无法用const对象(this)初始化非const对象。

 

};

 

const mycls b;

mycls b1 = c.Get();// 调用const版Get函数

const mycls b2 =c.Get(); // 调用const版Get函数

// b1 b2 定义时会调用类的拷贝函数。b1,b2是Get返回值的副本,b1还会将常量副本转变成变量

 

mycls &b3 =c.Get(); // 错误,不能用 const &mycls 初始化 &mycls (指针或者引用类型不能用常量初始化变量)

const mycls &b4 =c.Get();

 

 

mycls a;

mycls a1 = a.Get();// 调用非const版Get函数

const mycls a2 =a.Get(); // 调用非const版Get函数

       由此可见调用那个版本和调用对象是否const有关系,const对象会调用const版本,非const对象会调用非const版本。   

       引用网上的总结:

成员函数具有const重载时,类的const对象将调用类的const版本成员函数,类的非const对象将调用非const版本成员函数。

如果只有const成员函数,类的非const对象也可以调用const成员函数。                         ——这个思路来描述很囧。下同。

如果只有非const成员函数,类的const对象…额,不能调用非const成员函数。               ——其实跟上一句的意思是一样的:const对象只能调用它的const成员函数。

总的来说,就是当我们调用一个成员函数时,编译器会先检查函数是否有const重载,如果有,将根据对象的const属性来决定应该调用哪一个函数。如果没有const重载,只此一家,那当然就调用这一个了。这时编译器亦要检查函数是不是没有const属性而调用函数的对象又有const属性,若如此,亦无法通过编译。

版权声明:本文为博主原创文章,未经博主允许不得转载。

C++ Primer 第五版 中文版 练习 13.18 个人code

C++ Primer 第五版 中文版 练习 13.18 题目:定义一个Employee类,它包含雇员的姓名和唯一的雇员证号。 为这个类定义默认构造函数,以及接受一个表示雇员姓名的string的构造...
  • jierandefeng
  • jierandefeng
  • 2014年10月05日 11:37
  • 852

第十四章 14.5节练习 & 14.6节练习

练习14.26 为你的StrBl
  • chxw098
  • chxw098
  • 2014年09月17日 13:26
  • 469

C++ Primer中文本查询示例Query的实现

最近在看C++ Primer复习C++的语法,看到书中15.9章中的文本查询示例时,觉得设计得非常不错,于是便动手照着实现了一个,修改了很久终于运行成功了,从中也学习到了很多的语法。下面把实现与总结分...
  • zhaoxy2850
  • zhaoxy2850
  • 2014年07月20日 19:12
  • 2220

C++ Primer(第五版) 学习笔记

C++语言基础: 1. C++11增加了long long 类型,表示最小尺寸为64的整数。 2. 浮点数运算使用double,通常运算速度更快。 3. 超过int容量时使用long long类型,无...
  • zxh2075
  • zxh2075
  • 2016年10月25日 15:56
  • 477

14.6 && 14.7节练习

练习14.27 为你的StrBlobPtr类添加递增和递减运算符。 StrBlobPtr& StrBlobPtr::operator++() { check(curr, "increment pas...
  • Pierce_Liu
  • Pierce_Liu
  • 2016年06月20日 22:48
  • 219

《C++primer(第五版)》学习之路-第七章:类

【 声明:版权所有,转载请标明出处,请勿用于商业用途。  联系信箱:libin493073668@sina.com】   7.1 定义抽象数据类型   1.类的基本思想是数据抽象和封装,数据抽...
  • libin1105
  • libin1105
  • 2015年09月22日 23:01
  • 2188

C++ Primer笔记(十七)多重继承与虚继承

多重继承是从多于一个直接基类派生类的能力。多重继承的派生类继承其所有父类的属性。 为了支持多重继承,应扩充派生列表,多个类用逗号分割。如: class panda:public bear,publ...
  • woshibendangao
  • woshibendangao
  • 2014年04月27日 11:11
  • 1008

c++ Primer Plus(第六版)第十四章习题,写代码之路

c++ Primer Plus(习题14.1) //书上的测试文件,相当于客户的使用说明书 //对于书上那个Pair对象,不认真的人都怀疑是否学过 //竟然是一个模板,这道题目想了很久很久,还是没思...
  • Robot_x
  • Robot_x
  • 2017年02月08日 19:57
  • 275

C++ Primer 第五版第一章Sales_item.h源码

C++ Primer 第五版第一章Sales_item.h源码
  • soldersun
  • soldersun
  • 2015年11月20日 19:57
  • 1763

C++Primer第五版 第十六章习题答案(11~20)

类模版也是相当的重要,遇到过很多次,好好理解吧 11:知识点1:类模版的定义:与函数模版不同的是,编译器不会为类模版推断模版参数类型,所以我们在使用类模版时,需要显式地指出元素的类型,在其定义中,模版...
  • misayaaaaa
  • misayaaaaa
  • 2017年03月16日 09:41
  • 1202
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ Primer 类 12.1-12.2 this ,定义
举报原因:
原因补充:

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