zoukankan      html  css  js  c++  java
  • C/C++ 类与构造析构等知识

    简单定义类

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Student
    {
    public:
    	int uid;
    	char *name;
    	int age;
    
    public:
    	void set(int id, char *name, int age)
    	{
    		this->uid = id;
    		this->name = name;
    		this->age = age;
    	}
    	void display()
    	{
    		cout << this->uid << this->name << this->age << endl;
    	}
    };
    
    void Call(const Student &ptr)
    {
    	cout << ptr.name << endl;
    }
    
    int main(int argc, char *argv[])
    {
    	Student stu;   // 实例化
    
    	stu.set(1001, "lyshark", 23);                     // 设置数据
    	cout << stu.uid << stu.name << stu.age << endl;   // 输出
    	stu.display();                                    // 使用成员函数输出
    
    	Student *ptr = &stu;           // 使用指针
    	cout << ptr->uid << ptr->name << ptr->age << endl;
    
    	Call(stu);
    	system("pause");
    	return 0;
    }
    

    构造/析构 函数: 构造函数与类名相同,没有返回值,不写void,可以发生重载,可以有参数

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Student
    {
    public:
    	int uid;
    	char *name;
    	int age;
    
    public:
    	Student(int uid,char *name,int age)     // 构造函数
    	{
    		this->uid = uid;
    		this->name = name;
    		this->age = age;
    	}
    	~Student()                              // 析构函数
    	{
    		cout << "执行结束,析构 !" << endl;
    	}
    	void Display()
    	{
    		cout << this->name << endl;
    	}
    
    };
    
    int main(int argc, char *argv[])
    {
    	
    	class Student *stu_ptr[3];
    
    	Student stu1(1001, "admin", 22);
    	Student stu2(1002, "guest", 33);
    	Student stu3(1003, "tudyit", 25);
    
    	stu_ptr[0] = &stu1;
    	stu_ptr[1] = &stu2;
    	stu_ptr[2] = &stu3;
    
    	for (int x = 0; x < 3; x++)
    		stu_ptr[x]->Display();
    
    	system("pause");
    	return 0;
    }
    

    析构函数,没有返回值,不可以写参数,不能发生重载,多用于最后的类的清理左右。

    无参数构造函数(默认构造函数),有参数

    拷贝构造函数:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Student
    {
    public:
    	int uid;
    	char *name;
    	int age;
    
    public:
    	Student(int uid,char *name,int age)     // 构造函数
    	{
    		this->uid = uid;
    		this->name = name;
    		this->age = age;
    	}
    	Student(const Student& ptr)             // 拷贝构造函数
    	{
    		name = ptr.name;                    // 将 拷贝参数赋值给被拷贝类中
    		cout << "kaobei" << endl;
    	}
    };
    
    int main(int argc, char *argv[])
    {
    	Student stu1(1001, "admin", 22);
    	
    	// 拷贝构造函数:括号法调用
    	// 调用拷贝构造函数 stu1 拷贝到stu2中
    	Student stu2(stu1);
    	cout << stu2.name << endl;
    
    	Student stu3 = Student(stu1);
    	cout << stu3.name << endl;
    
    	system("pause");
    	return 0;
    }
    

    浅拷被: 容易崩溃,系统简单的传值,出现问题。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Student
    {
    public:
    	char * m_name;
    	int m_age;
    
    public:
    	Student()
    	{
    
    	}
    	Student(char * name, int age)
    	{
    		m_name = (char *)malloc(strlen(name) + 1);
    		strcpy(m_name, name);
    	}
    	~Student()
    	{
    		if (m_name != NULL)
    			free(m_name);
    	}
    
    };
    
    
    int main(int argc, char *argv[])
    {
    	Student stu1("lyshark",25);
    	// < 浅拷贝,出现了崩溃的问题> 因为执行了两次析构,出现了冲突
    	Student stu2(stu1);            // 调用拷贝构造函数
    
    	system("pause");
    	return 0;
    }
    

    深拷贝: 自己开辟堆空间,然后自己在拷贝构造函数中拷贝数据,防止冲突,同样的代码不会出现问题了。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Student
    {
    public:
    	char * m_name;
    	int m_age;
    
    public:
    	Student()
    	{
    
    	}
    	Student(char * name, int age)
    	{
    		m_name = (char *)malloc(strlen(name) + 1);
    		strcpy(m_name, name);
    	}
    	~Student()
    	{
    		if (m_name != NULL)
    			free(m_name);
    	}
    	Student(const Student &ptr)
    	{
    		m_age = ptr.m_age;
    		m_name = (char *)malloc(strlen(ptr.m_name) + 1);
    		strcpy(m_name, ptr.m_name);     // 深层拷贝
    	}
    };
    
    int main(int argc, char *argv[])
    {
    	Student stu1("lyshark",25);
    	// < 浅拷贝,出现了崩溃的问题> 因为执行了两次析构,出现了冲突
    	Student stu2(stu1);            // 调用拷贝构造函数
    
    	system("pause");
    	return 0;
    }
    

    多个对象的构造和析构:初始化列表

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Student
    {
    public:
    	char * m_name;
    	int m_age;
    
    public:
    	Student(char * x, int y) :m_name(x), m_age(y){}
    };
    
    
    int main(int argc, char *argv[])
    {
    	Student stu("lyshark",23);
    	cout << stu.m_name << stu.m_age << endl;
    
    
    	system("pause");
    	return 0;
    }
    

    explicit 关键字的作用 该关键字为了防止隐世类型转换,就是防止你瞎搞。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class MyString
    {
    public:
    	char * m_Str;
    
    public:
    	MyString(const char *str)
    	{
    
    	}
    	// 该关键字为了防止隐世类型转换
    	explicit MyString(int num)
    	{
    
    	}
    
    };
    
    
    int main(int argc, char *argv[])
    {
    	MyString str = "lyshark";    // 显示调用
    
    	// MyString str2 = 10;
    
    	system("pause");
    	return 0;
    }
    

    new 动态对象创建: 忘记 malloc() /free 吧,new 可以自动分配初始化空间,非常方便。开辟空间到堆。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Student
    {
    public:
    	char * m_Str;
    
    public:
    	Student()
    	{
    		cout << "默认构造调用" << endl;
    	}
    	~Student()
    	{
    		cout << "默认析构调用" << endl;
    	}
    };
    
    
    int main(int argc, char *argv[])
    {
    	// Student stu1;        // 在站区开辟空间
    
    	// 所有new出来的对象都会返回该类型的指针
    	// malloc 返回 void* 还必须要强转
    	// new 会调用构造函数? new 并不是函数而是运算符
    
    	Student *stu2 = new Student;   // 堆区开辟空间
    	// 释放堆空间
    	delete stu2;
    
    	// new 来开辟数组 , 他一定会调用默认构造函数,有多少数组成员就调用多少次!
    	Student *pArray = new Student[10];
    
    	pArray[0].m_Str = "lyshark";
    
    	cout << pArray[0].m_Str << endl;
    
    	// 释放整个数组,必须加[] 中括号
    	delete [] pArray;
    
    
    	system("pause");
    	return 0;
    }
    

    静态成员变量: static声明就是静态成员变量,无论建立多少对象,都只有一个静态数据的拷贝,所有对象都共享这个静态数据。

    #include <iostream>
    
    using namespace std;
    
    class Student
    {
    public:
    	// 静态成员变量,在类内声明,在类外初始化
    	static int m_number;  // 定义静态变量
    };
    
    int Student::m_number = 100;      // 类外初始化实现
    
    int main(int argc, char *argv[])
    {
    	Student stu1, stu2;
    	
    	stu1.m_number = 200;  // stu1赋值后,会影响stu2里面的,两个是共享数据的
    
    	cout << stu1.m_number << endl;
    	cout << stu2.m_number << endl;
    	cout << "通过类名直接访问:"<< Student::m_number << endl;
    
    	system("pause");
    	return 0;
    }
    

    静态成员函数:

    #include <iostream>
    
    using namespace std;
    
    class Student
    {
    public:
    	static void Display()
    	{
    		cout << "hello lyshark" << endl;
    	}
    };
    
    
    int main(int argc, char *argv[])
    {
    	Student stu1,stu2;
    
    	// 静态成员函数,不可以访问普通成员变量
    	// 但是可以访问静态成员变量
    
    	stu1.Display();     // 两个对象同样是调用的一个函数。
    	stu2.Display();
    
    	system("pause");
    	return 0;
    }
    

    单例模式设计思想: 一个类中,是能实例化出一个对象,这样就可以防止冲突的情况发生。

    想想,如何实现,不论new多少次,始终只能保证,创建一个对象,不多创建。

    #include <iostream>
    
    using namespace std;
    
    // 创建列中的对象,并且保证只有一个对象可以使用,一个对象实例。
    
    class ChairMan
    {
    private:
    	// 1.将构造函数自由化,改成private
    	// 
    	ChairMan(){ cout << "create super" << endl; }
    public:
    	static ChairMan *singleMan;
    
    };
    
    ChairMan * ChairMan::singleMan = new ChairMan;
    
    int main(int argc, char *argv[])
    {
    	cout << "main" << endl;  // 主席创建,先于 main
    	ChairMan::singleMan;
    
    	ChairMan *cm1 = ChairMan::singleMan;
    
    
    
    	system("pause");
    	return 0;
    }
    

    安全的改进

    #include <iostream>
    
    using namespace std;
    
    // 创建列中的对象,并且保证只有一个对象可以使用,一个对象实例。
    
    class ChairMan
    {
    private:
    	// 1.将构造函数自由化,改成private
    	// 
    	ChairMan(){ cout << "create super" << endl; }
    	ChairMan(const ChairMan &ch) {};
    private:
    	static ChairMan *singleMan;
    public:
    	// 通过提供的接口实现访问
    	static ChairMan* getInstance()
    	{
    		return singleMan;
    	}
    };
    
    ChairMan * ChairMan::singleMan = new ChairMan;
    
    int main(int argc, char *argv[])
    {
    	ChairMan * cm1 = ChairMan::getInstance();
    	ChairMan * cm2 = ChairMan::getInstance();
    	if (cm1 == cm2)
    		cout << "相等" << endl;
    
    	// 现在其实也能改? 下面可以强改,加上拷贝构造,直接完事。
    	ChairMan *cm3 = new ChairMan(*cm2);
    	if (cm2 == cm3)
    		cout << "不相等" << endl;
    
    
    	system("pause");
    	return 0;
    }
    

    打印机的单例模式案例。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Printer
    {
    private:
    	static Printer * singlePrinter;
    
    private:
    	Printer(){ };
    	Printer(const Printer & ptr);
    
    public:
    	static Printer * getInstance()
    	{
    		return singlePrinter;
    	}
    	static void PrintText(string text)
    	{
    		cout << text << endl;
    	}
    };
    
    Printer * Printer::singlePrinter = new Printer;
    
    
    int main(int argc, char *argv[])
    {
    	// 拿到打印机对象指针,后期通过该指针操作数据
    	Printer * ptr = Printer::getInstance();
    
    	ptr->PrintText("hello lyshark");   // 调用打印机
    
    	system("pause");
    	return 0;
    }
    

    this 指针: this指针指向被调用的成员函数所属的对象,

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Person
    {
    public:
    	char *name;
    	int age;
    
    public:
    	Person(char *p_name, int p_age) { this->name = p_name; this->age = p_age; }
    
    	void Compare_Age(Person & ptr)       // 对比年龄是否相等
    	{
    		if (this->age == ptr.age)
    			cout << "Same age" << endl;     // 年龄相同
    		else
    			cout << "Same not age" << endl; // 年龄不同
    	}
    
    	void PlusAge(Person & ptr)   // 两个年龄相加
    	{
    		this->age += ptr.age;
    	}
    
    	Person & Push_Age(Person &ptr)
    	{
    		this->age += ptr.age;
    		return *this;         // 返回指向对象本体
    	}
    
    };
    
    int main(int argc, char *argv[])
    {
    	Person per1("lyshark", 33);
    	Person per2("admin", 33);
    	// ----------------------------------------
    	per1.Compare_Age(per2);      // 判断两个类年龄是否相等
    	// ----------------------------------------
    	per1.PlusAge(per2);          // 将两个年龄相加
    	cout << per1.age << endl;    // 输出年龄
    	// ----------------------------------------
    
    	per1.Push_Age(per2).Push_Age(per2);  // 链式编程(必须传递引用)
    	cout << per1.age << endl;
    
    	system("pause");
    	return 0;
    }
    

    空指针访问成员函数: 如果用不到this则可以调用,用到的话就会报错。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Person
    {
    public:
    	int m_age;
    
    public:
    	void show() { cout << "person show" << endl; }
    	void show_age() 
    	{
    		if (this == NULL)   // 防止使用空指针访问
    			return;
    		cout << "show: "<< m_age << endl;
    	}
    };
    
    int main(int argc, char *argv[])
    {
    
    	Person *ptr = NULL;
    
    	ptr->show();          // 这个可以
    	ptr->show_age();      // 不可以
    
    	// show_age() 默认会加上 this --> 那么如果传递空指针则失败
    	// 代码接收空指针,会溢出
    
    	system("pause");
    	return 0;
    }
    

    常函数、常对象: 使用const 修饰成员函数,则是常函数,

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Person
    {
    public:
    	int m_x;
    	int m_y;
    
    public:
    	Person()
    	{
    		this->m_x = 0;
    		this->m_y = 0;
    	}
    
    	void showInfo() const // 声明常函数,函数内部不可有修改指针的指向
    	{
    		 // this->m_x = 1000; 相当于修改成了: --> const Person * const this
    		cout << this->m_x << endl;
    		cout << this->m_y << endl;
    	}
    };
    
    
    int main(int argc, char *argv[])
    {
    	Person per1;
    	per1.showInfo();
    
    	// 定义常对象,常对象不允许修改数据。
    	const Person per2;
    
    	system("pause");
    	return 0;
    }
    

    友元函数的定义(全局函数): 将全局函数定义为友元函数,让外部函数,可以访问类内部的私有数据。

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Building
    {
    
    	friend void goodGay(Building *building);
    private:
    	string m_badRoom;        // 私有的卧室
    	string m_sittingRoom;    // 客厅
    
    public:
    	Building()
    	{
    		this->m_sittingRoom = "客厅";
    		this->m_badRoom = "卧室";
    	}
    };
    
    // 全局函数,我想让他能访问到私有的卧室
    void goodGay(Building *building)
    {
    	cout << "访问我的客厅:" << building->m_badRoom << endl;
    	cout << "访问我的卧室:" << building->m_sittingRoom << endl;
    
    }
    
    int main(int argc, char *argv[])
    {
    	Building *building = new Building;
    	goodGay(building);
    
    
    	system("pause");
    	return 0;
    }
    

    让整个类做友元类:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Teacher
    {
    	friend class Student;  // 让Student学生,可以访问我的私有成员
    
    private:
    	char * m_school;     // 老师所在的学校
    	char * m_class;      // 老师所教的班级
    
    public:
    	Teacher()
    	{
    		this->m_school = "中心小学";
    		this->m_class = "一年级二班";
    	}
    };
    
    class Student
    {
    private:
    	Teacher *ptr;         // 设置一个指向teacher的指针
    
    public:
    	Student()
    	{
    		ptr = new Teacher; // 初始化一下
    	}
    	void Display()
    	{
    		cout << "学生访问到的学校: " << this->ptr->m_school << endl;
    		cout << "学生访问到的班级: " << this->ptr->m_class << endl;
    	}
    };
    
    int main(int argc, char *argv[])
    {
    
    	Student stu;
    	stu.Display();
    
    	system("pause");
    	return 0;
    }
    
    文章出处:https://www.cnblogs.com/LyShark/p/12874267.html
    版权声明:本博客文章与代码均为学习时整理的笔记,博客中除去明确标注有参考文献的文章,其他文章 [均为原创] 作品,转载请 [添加出处] ,您添加出处是我创作的动力!

    如果您恶意转载本人文章并被本人发现,则您的整站文章,将会变为我的原创作品,请相互尊重 !
    转载规范 点击阅读 如果您转载本人文章,则视为您默认同意此规范约定。
  • 相关阅读:
    android webview cookie同步
    session和cookie
    对称加密与非对称加密
    理解java回调机制
    android studio命令
    android studio友盟gradle多渠道打包
    [c++] final override keyword
    [C++] Returning values by reference in C++
    [c++] polymorphism without virtual function
    [C++] NEW Advanced Usage
  • 原文地址:https://www.cnblogs.com/LyShark/p/12874267.html
Copyright © 2011-2022 走看看