您的位置:首页 > 编程语言 > C语言/C++

C++入门学习笔记(一)--面向对象基本概念

2015-12-21 19:29 816 查看

0、引言

C++比较繁杂、内容很多,并且保留了C的特性,不是完全面向对象(OOP)的语言,总体上讲内容包含四个部分:C语言,面向对象,模板编程,STL库。C++是面向对象的C,C++是C语言的一个超集,面向对象的三大机制是:封装,继承,多态。

1、面向对象之封装

虽然C语言是面向过程的,但它也提供了一些面向对象的理念,比如结构体(struct)。结构体可以对数据变量(属性)进行封装,但无法直接对方法进行封装(使用函数指针可以间接实现),而且没有访问权限的概念,它的数据成员都对外部都是可见的。C++中引入了关键字类class,在更高层次上实现抽象与封装,同时在C++中也保留了结构体关键字(struct),struct 与 class 在C++中都用于声明类,只是在成员的默认访问权限上有所区别,struct默认是public, 而class默认是private。C++中类的成员变量(面向对象中一般称为属性)与成员函数(方法),成员函数可以重载。围绕着成员变量主要的语法知识就是类对象的定义,访问权限,构造函数、复制构造函数,函数重载,作用域,const声明,this指针,inline,友元等。

#ifndef PERSON_H
#define PERSON_H
#include <string>
#include <iostream>
using namespace std;
class Person;
void Printf(const Person &p );
class Person
{
public://
Person();
Person(const string name, int const age);
Person(const string name, int const age,const int height);
void SetName(const string strName);
inline void SetAge(const int age);//inline 函数如果在类在外部实现,则必须在当前文件里
const Person &SetHeight(const int height) const;
Person &SetHeight(const int height);// const 函数与非const 函数形成重载
string GetName(void) const;
int GetAge(void)const ;
static int GetPersonNum();
friend void Printf( const Person &p );
static void SetStaticData(const int data)
{
m_personNUM = data;
}
void Output()//
{
cout<<"----------Person ----------"<<endl;
cout<<"the Person's name : "<<m_name<< endl;
cout<<"the Person's age : "<<m_age<< endl;
cout<<"the Person's height : "<<m_height<< endl;
cout<<"the Person's personNum : "<<m_personNUM<< endl;
cout<<"the Person's contryID : "<<m_contryID<< endl;
cout<<"the Person's constTemp : "<<constTemp<< endl;
cout<<"-----------------------------<<endl;
}
~Person();
protected:
// add code
private:
string m_name;
int m_age;
int m_height;
static int m_personNUM;// static
const static int m_contryID = 10086;
const int constTemp;
//int &m_id;//
};// end of class Person
inline void Person::SetAge(const int age)
{
this->m_age = age;
}
#endif // end of <span style="font-family: 宋体;">PERSON_H</span>


1.1访问权限

在类内部代码,一般情况下变量与函数可以任意访问,不受限制;在类外部,主要对是类的使用者而言,程序可以访问类的公有成员与保护成员。访问权限的很好的体现的封装理念。即类把实现细节隐藏了,类的使用都只需使用类的接口(公有接口)就行了。

1.2构造函数

构造函数名与类名相同,没有返回值。在类的定义中,如果没有明确定义类的结构函数,则编译器一般会自动为类添加默认构造函数(这个构造函数是编译器认为“必要”),默认函数是不带参数的构造函数,用于类对象的初始化处理工作。构造函数可以是私有的。构造函数也可以重载,通过参数来决定选用哪个构造函数构造对象,以提供给用户多种构造方法。

1.2.1 构造函数初始化列表

构造函数的目的是初始化类对象的数据成员,一般有两种方法:可以在构造函数体内实现成员变量的赋值初始化,也可使用初始化列表实现。初始化列表先于构造函数休赋值操作执行,在初始化列表中没有显示的初始化成员,使用该类型的默认构造函数构造,如果没有默认构造函数,且没有在列表中显示初始化,则会出现编译错误。有三种情况下必须使用初始化列表,不能直接构造函数体内直接赋值操作:

A、类成员当中有没有默认构造函数的类类型,

B、Const 成员变量,

C、声明为引用的成员变量。

成员初始化顺序。在初始化列表中,各个成员的初始化顺序与成员变量的在类中声明的顺序一致。在Person类的构造函数中:

Person::Person(const string name, int const age,const int height)/
:m_name(name),m_height(age),m_age(m_height)
{  }
在上面类的构造函数的初始化列表(为了说明,故意而这样为之)中,m_age比m_height先初始化,先用一个未知值(m_height)去初始化m_age,然后m_age得到是未知值,这与编程者的本意是相悖的。所以在构造函数的初始化列表中,按照成员变量的声明顺序初始化。

1.3 内联函数

内联成员函数是在成员函数的声明前直接加上关键字inline或者函数的实现在类内部如Person 类中的Persosn::Output()函数。inline函数是通过编译器直接在函数的调用处扩展代码,当内联函数在类的外部实现时,函数体必须与类的定义处于同一文件内,否则会出现链接编译错误,在Person 类中,成员SetAge()函数的定义放在类外,但其定义是与Person类的定义都处于一个person.h文件中的。

1.4 const 关键字

1.4.1 const 成员变量

在类的内部无法使用#define 来定义常量,但可以enmu关键定来实现,在C++中推荐使用const在实现常量定义,如Person::constTemp变量。用const 定义的常量,必须在构造函数的初始化列表中实现初始化,否则出现编译错误,在本例类中,三个构造函数都使用了初始化列表初始化constTemp。

1.4.2 const 成员函数

Const 成员函数是在函数声明的后面加上const 关键字,如Person 类中的声明:

const Person &SetHeight(const int height) const;
const成员函数提供了一种用户应用程序访问类的内部数据,但不允许修改内部数据的机制,即const 函数不能修改成员变量,只能访问成员变量。Const 函数与非const函数可以形成重载。如Person 类中下面操作注意const 成员函数只在类内部有,区别于返回值类型为const 的函数。SetHeight
()是一个const 成员函数,同时其返回值的类型也是const。

const Person &Person::SetHeight(const int height) const
{
//this->m_height = height;// error, 不能修改成员值
return *this;
}
Person &Person::SetHeight(const int height)//非const 函数形成重载
{
this->m_height = height;
return *this;
}


1.5 友元

友元是提供了另外一种机制,即非类的成员可以访问类的所有成员数据(包括私有)。友元可以一个前向声明的函数,也可以是类或者类的某个函数,但都必须是前向声明,即之前已经声明过。在Person 类友元使用如下。

void Printf(const Person &p );// 前向声明
void Printf(const Person &p )
{
cout<<"the Person's name : "<<p.m_name<< endl;// 访问友元函数有私有成员
cout<<"the Person's age : "<<p.m_age<< endl;
cout<<"the Person's age : "<<p.m_height<< endl;
}


1.6 static 成员

Static 成员是属于类本身,不是属于某个类对象。Static成员变量在内存上它是放在全局数据区。

Static变量不属于类对象,所以它的访问是通过类名直接访问(当然对象也是可以访问的),如Person 类中有一个m_perosnNUM变量。static 成员变量的定义需在类外重新实现。

Static成员函数也是属于类本身,它能问类的static 成员变量,不能访问非成员变量,非Static 成员函数可以访问static 成员变量。

1.7 作用域

作用域是C++专门引入的,主要目的是用以解决名字冲突问题。如在本程序中perosn.h 中using
namespace std; 是一个作用域声明,后面程序中就可以直接使用std::下的函数和变量了,如果cout等。

每个类也定义了自己的作用域,即类内所有函数成员可以访问类的所有成员变量。

类成员函数定义中的名字查找顺序:

1、先查找函数内的局部变量,

2、查找类的成员变量,

3、查找类外变量声明,外围作域,即大”{}”,”{}”表示一个作用域,

4、全文件查找。
参考文献《C++ primer》 《Effective c++》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: