zoukankan      html  css  js  c++  java
  • 从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(); 
    } 
    
  • 相关阅读:
    Swift app中的Crash捕获与处理
    10 Things ASP.NET Developers Should Know About Web.config Inheritance and Overrides(转)
    Browserify使用指南(转)
    开启mac terminal 命令/路径自动补全功能
    selenium--定位元素
    selenium--断言方法
    selenium--unittest框架
    苹果手机对应版本
    Pycharm2019激活
    接口上传图片方法
  • 原文地址:https://www.cnblogs.com/cl94/p/13976174.html
Copyright © 2011-2022 走看看