zoukankan      html  css  js  c++  java
  • 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是与特定对象绑定在一块的。

  • 相关阅读:
    L2-004. 这是二叉搜索树吗?
    CF934A A Compatible Pair
    CF937B Vile Grasshoppers
    CF940B Our Tanya is Crying Out Loud
    ZOJ 3182 Nine Interlinks
    ZOJ 3175 Number of Containers
    Codeforces Round #193 (Div. 2) B
    CodeForces 149D Coloring Brackets
    POJ 2653 Pick-up sticks(计算几何)
    UVA 12506 Shortest Names
  • 原文地址:https://www.cnblogs.com/xfxu/p/3989488.html
Copyright © 2011-2022 走看看