• 从c到c++(2)


    1.类的定义

    c++的struct是在c的struct类型上,增加了成员函数
    c的struct可将一个概念或实体的所有属性组合在一起,描述同一类对象的共同属性
    c++使struct不但包含数据,还包含函数用于访问或修改变量

    #include <iostream>
    #include <cmath>
    using namespace std; 
    
    struct Date{
    	int d, m, y;
    	void init(int dd, int mm, int yy){ 
    		d = dd;
    		m = mm;
    		y = yy; 
    	} 
    	void print(){
    		cout << y << "-" << m << "-" << d << endl; 
    	}
    	Date& add(int dd){
    		d = d + dd;
    		return *this; // this是指向这个函数的类型对象指针
    		// *this解引用,是这个函数的对象
    		// 这个函数返回的是自引用。可以实现链式调用 
    	} 
    	// 成员函数重载+=运算符实现更直观的add 
    	Date& operator+= (int dd) {
    		d = d + dd;
    		return *this; 
    	} 
    };
    int main(){
    	Date day;
    	day.print();
    	day.init(4, 6, 1999);
    	day.add(1).add(1); 
    	(day += 1) += 1; 
    	day.print();
    } 
    

    2.构造函数与析构函数

    #include <iostream>
    #include <cstring>
    
    using namespace std; 
    
    struct Person{
    	int age;
    	char *name; 
    	// 构造函数。注:构造函数可以重载 
    	Person(char *n = "on_name", int a = 0){
    		int len = strlen(n);
    		// 申请内存 
    		name = new char[len + 1]; // +1给留位置 
    		strcpy(name, n); // 字符串拷贝 
    		age = a;
    		cout << "构造完毕" << endl;
    	}
    	// 析构函数
    	virtual ~Person(){
    		// 释放内存 ,防止内存泄漏 
    		delete[] name; 
    		cout << "析构完毕" << endl;
    	}
    };
    int main(){
    	Person p("小明", 5);
    	cout << p.name << "--" << p.age << endl;
    } 
    

    3.访问控制与接口

    class比struct多了访问控制与接口

    #include <iostream>
    #include <cstring>
    
    using namespace std; 
    
    // 把struct改成class之后要用public修饰才能达到和之前一样的效果,不然回报错,因为class里面的成员变量和成员函数默认是private的 
    class Person{
    // public:之后的成员函数和成员变量是公开的 
    public: 
    	int age;
    	char *name; 
    	// 构造函数。注:构造函数可以重载 
    	Person(char *n = "on_name", int a = 0){
    		int len = strlen(n);
    		// 申请内存 
    		name = new char[len + 1]; // +1给留位置 
    		strcpy(name, n); // 字符串拷贝 
    		age = a;
    		cout << "构造完毕" << endl;
    	}
    	// 析构函数
    	virtual ~Person(){
    		// 释放内存 ,防止内存泄漏 
    		delete[] name; 
    		cout << "析构完毕" << endl;
    	}
    };
    int main(){
    	Person p("小明", 5);
    	cout << p.name << "--" << p.age << endl;
    } 
    

    4.拷贝:拷贝构造函数

    硬拷贝带来的问题

    #include <iostream>
    #include <cstring>
    
    using namespace std; 
    
    class Person{
    public: 
    	int age;
    	char *name; 
    	// 构造函数。注:构造函数可以重载 
    	Person(char *n = "on_name", int a = 0){
    		int len = strlen(n);
    		// 申请内存 
    		name = new char[len + 1]; // +1给留位置 
    		strcpy(name, n); // 字符串拷贝 
    		age = a;
    		cout << "构造完毕" << endl;
    	}
    	// 析构函数
    	virtual ~Person(){
    		// 释放内存 ,防止内存泄漏 
    		delete[] name; // 由于硬拷贝,p和p1的name指向同一块内存,而它们的析构函数分别会执行一次,所以会对同一块内存释放两次 ,从而出错 ,解决方案如下 
    		cout << "析构完毕" << endl;
    	}
    	
    	// 解决上述硬拷贝带来的问题,重写拷贝构造函数,实现浅拷贝
    	Person(Person &p){
    		age = p.age;
    		// 让拷贝构造函数的成员不指向同一块内存,从而避免析构函数对同一块内存释放两次的问题 
    		int len = strlen(p.name);
    		name = new char[len + 1]; // +1给留位置 
    		strcpy(name, p.name); // 字符串拷贝 
    	} 
    };
    int main(){
    	Person p("小明", 5);
    	// 调用拷贝构造函数 ,如不重写该构造函数,属于硬拷贝 
    	Person p1(p);
    	cout << p.name << "--" << p.age << endl;
    	cout << p1.name << "--" << p1.age << endl;
    } 
    

    5.类模板:我们可以将一个类变成类模板或模板类,正如一个模板函数一样

    #include <iostream>
    using namespace std; 
    
    // 类模板实现数组存放所有的类型 
    template <class T> 
    class Array{
    	int size;
    	T *data;
    public: 
    	Array(int s){
    		// 数组长度 
    		size = s;
    		// 数组的数据 
    		data = new T[s];
    	}
    	// 析构函数
    	~Array(){
    		delete[] data; 
    	}
    	// 运算符重载
    	T& operator [](int i){
    		if(i < 0 || i >= size){
    			cout << "err"; 
    			throw "out of index"; 
    		}
    		return data[i];
    	}
    	// 遍历数组
    	void show(){
    		for(int i = 0; i < size; i++){
    			cout << data[i] << endl;
    		}
    	} 
    };
    
    int main(){
    	int n = 2;
    	// <int> 表示 T是int类型 
    	Array<int> t(n);
    	t[0] = 1;
    	// 两次利用了运算符重载,实现了数组使用键赋值和获取值 
    	t[1] = t[0] + 1;
    	// t[2] = 3; 会触发错误 
    	t.show();
    } 
    

    6.string

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std; 
    
    int main(){
    	// string对象的初始化 
    	string s("HELLO");
    	s = "DEMO"; // 赋值运算符 
    	
    	// 常量迭代器
    	string::const_iterator cii;
    	int ii = 0;
    	for(cii = s.begin(); cii != s.end(); cii++){
    		cout << ii++ << " " << *cii << endl;
    	}
    	
    	// 向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container) 
    	// 跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。
    	vector<int>obj;//类模板的使用方法,创建一个向量存储容器 int
    	for(int i=0;i<10;i++) // push_back(elem)在数组最后添加数据 
        {
            obj.push_back(i);
            cout<<obj[i]<<",";    
        }
    } 
    

    7.继承:一个派生类从1个或多个父类继承,既继承父类的属性和行为,但也有自己的特有属性和行为

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std; 
    
    class Person{
    public: 
    	string name;
    	void say(){
    		cout << "i am " << name;
    	}
    }; 
    class Teacher: public Person{
    public: 
    	Teacher(string n){
    		name = n;
    	}
    };
    
    int main(){
    	Teacher a("白白");
    	a.say(); 
    } 
    
  • 相关阅读:
    为图片指定区域添加链接
    数值取值范围问题
    【leetcode】柱状图中最大的矩形(第二遍)
    【leetcode 33】搜索旋转排序数组(第二遍)
    【Educational Codeforces Round 81 (Rated for Div. 2) C】Obtain The String
    【Educational Codeforces Round 81 (Rated for Div. 2) B】Infinite Prefixes
    【Educational Codeforces Round 81 (Rated for Div. 2) A】Display The Number
    【Codeforces 716B】Complete the Word
    一个简陋的留言板
    HTML,CSS,JavaScript,AJAX,JSP,Servlet,JDBC,Structs,Spring,Hibernate,Xml等概念
  • 原文地址:https://www.cnblogs.com/cl94/p/13976174.html
Copyright © 2020-2023  润新知