C++OOP之类和对象 ---第一个特征:数据抽象

 C++中的结构体:(不可访问整个结构体,如:不能一次输出结构体。)

1):在C中,结构体只可以含有成员,不可以有函数,但是c++中可以。而且,函数可以直接访问里面的数据成员。

2):访问方式

a):若是结构体类型的  变量, 采用  .  形式。如:Person.Age_。

b):若是结构体类型的 指针, 则采用 -> 形式。如  it->Age_.

 类:

1):类的访问属性:(默认是private)

public:元素是公开的,任何位置都可以访问;

private:成员是私有的,只能在类的内部访问。

我们一般采用的方案是:把  类的成员变量  设为private, 把   类的成员函数  设为public。

这样我们只能通过 函数  设置或者获取其成员变量的值。

示例代码如下:

#include <iostream>
#include <string>
using namespace std;

class Person 
{
	private:
		int _id;
		string _name;
		int _age;

	public:
		int get_id() const //保护本对象
		{  return _id; 	}

		void set_id(int id) 
		{ _id = id; }

		string get_name() const 
		{	return _name;	}

		void set_name(const string &name) 
		{ _name = name; }

		int get_age() const 
		{	return _age; }

                void set_age(int age) 
		{	_age = age;	}

		void print(std::ostream &os) 
		{	os << "id: " << _id << " name: " << _name << " age: " << _age << endl;	}
};

int main()
 {
	//编译错误,不可以直接访问。 
/* Person p1; p1._age = 99; p1._id = 00123; p1._name = "Jack"; p1.print(cout); Person *p2 = new Person; p2->_age = 34; p2->_id = 12345; p2->_name = "hello"; p2->print(cout); */
//修改如下:
    Person p;
    p.set_age(23);
    p.set_id(1234);
    p.set_name("zhangsan");
    p.print(cout);     }

 2): 成员函数:

四要素: 函数返回类型, 函数名, 形参表, 函数体。

注意:

a): 成员函数含有额外的形参;

调用成员函数是,实际上是使用对象来调用的,例如p1.print(cout),在此调用中,传递了对象cout,但是print 是如何知道打印 哪个对象的属性呢?  因此,这里实际上 把 p1 也作为一个参数传递给print。

b):this 指针的引入(用于解决返回自身的值或者引用):

每一成员函数都有隐含的形参 就是 this 指针。 这个参数 指向调用对象的地址。

例如在 p1。print(cout)中,print中的this指针 就指向 p1 的地址。

c):const成员函数:

 如:string get_name() const

此处const的含义是, get_name这个函数不能修改 本对象。其实就是不得对 类的数据成员进行修改。

注意:  普通对象可以调用const函数,也可以调用非const函数, 但是const对象只能调用const对象。(语义--->只读)

 3):const成员函数 和 普通函数可以构成重载。

const成员 必定 调用 const 成员函数。

重载的要素: 函数名(必须一样), 函数形参表, 类的名称, 成员函数的const属性。

C语言中没有函数重载, 因为C函数 的唯一标识  是 函数名称。(产生重定义);

而C++ 函数的唯一标识 是 函数名称 和 参数表 构成。

 1         void print(std::ostream &os) 
 2     {
 3         os << "id: " << _id << " name: " << _name << " age: " << _age << endl;
 4     }
 5 
 6     void print(std::ostream &os) const
 7      {
 8         os << "id: " << _id << " name: " << _name << " age: " << _age << endl;
 9     }
10 };
11     

 4):构造函数

构造函数式特殊的成员函数,与类同名,且没有返回类型 ;

一个类 可以有多个构造函数,构造函数必有不同数目或者类型的形参列表。

注意:每个类都有默认的构造函数,当我们自己定义了一个新的构造函数时,如果我们不显式写出默认构造函数,程序将会 自动执行 我们新定义的构造函数。这就可能造成一些错误。

示例代码如下:

 1 class Person
 2 {
 3     public:
 4     //修改之处:增加默认构造函数即可
 5         Person() //默认构造函数
 6             :Age_(0),Name_("")
 7         { }
 8         
 9         Person(int age, const string name)
10             :Age_(age),Name_(name)
11         { }
12     
13     private:
14         int Age_;
15         string Name_;
16 }
17 
18 int main()
19 {
20     Person p1;//编译错误。没有显式提供默认构造函数。
21     Person p2(23, "zhangsan"); //ok
22 }

构造函数之初始化式:(如上示例代码)

必须使用初始化列表的情形:

i):没有默认构造函数的类成员;

ii):const成员;

iii):引用类型的成员;

iiii)类成员需要显式调用含参数的构造函数。

考虑下面的类:

class X
{
	private:
		int i;
		int j;
	
	public:
		X(int val)    //若 val 为 35, 则 i=0 ;j = 35;
			:j(val),i(j)
		{}
};

 我们设想的是 用 val 初始化 j, 用 j 的值初始化 i,但是这里初始化的次序 是 先 i 后 j;

5):析构函数:

  ~Person()

  {} 

再谈this指针:this指针最大的作用就是返回自身的引用。

示例代码如下:

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 class Person {
 6 private:
 7     int _id;
 8     string _name;
 9     int _age;
10 
11 public:
12 
13     Person() :
14             _id(-1), _name("none"), _age(-1) 
15         {
16     }
17 
18     Person(int id, const string &name, int age) :
19             _id(id), _name(name), _age(age) 
20         {
21     }
22 
23     Person &set_id(int id) 
24         {
25         _id = id;
26         return *this;
27     }
28 
29     Person &set_name(const string &name) 
30         {
31         _name = name;
32         return *this;
33     }
34 
35     Person &set_age(int age) 
36         {
37         _age = age;
38         return *this;
39     }
40 
41     Person &print(std::ostream &os)
42      {
43         os << "id: " << _id << " name: " << _name << " age: " << _age << endl;
44         return *this;
45     }
46 
47     const Person &print(std::ostream &os) const
48      {
49         os << "id: " << _id << " name: " << _name << " age: " << _age << endl;
50         return *this;
51     }
52 
53 };
54 
55 int main(int argc, char **argv) {
56     Person p;
57     p.print(cout);
58     p.set_id(12).print(cout).set_age(22).print(cout).set_name("hello").print(
59             cout);
60 }
61     


上述程序 运行结果为:12,22,helllo 并且 其调用的print函数 都是 Person print()类型。

(若加上析构函数,则1次销毁)。

若不加&,则运行的是 同一对象的 多个副本。总共7个。 调用几次成员函数,则生成几个副本。

(若加上析构函数,则7次“销毁”)

Static:

static变量不能与this指针绑定。既然static变量属于整个类,那么 就不属于特定的某一个对象。

而this是与特定对象绑定在一块的。

原文地址:https://www.cnblogs.com/xfxu/p/3989488.html