桂林北站改造,淘宝客网站建设分类,浙江省建设局房管科网站,最近一周的新闻大事10条C/C语言是一种通用的编程语言#xff0c;具有高效、灵活和可移植等特点。C语言主要用于系统编程#xff0c;如操作系统、编译器、数据库等#xff1b;C语言是C语言的扩展#xff0c;增加了面向对象编程的特性#xff0c;适用于大型软件系统、图形用户界面、嵌入式系统等。…C/C语言是一种通用的编程语言具有高效、灵活和可移植等特点。C语言主要用于系统编程如操作系统、编译器、数据库等C语言是C语言的扩展增加了面向对象编程的特性适用于大型软件系统、图形用户界面、嵌入式系统等。C/C语言具有很高的效率和控制能力但也需要开发人员自行管理内存等底层资源对于初学者来说可能会有一定的难度。
使用结构体定义类: 其实使用C语言中的结构体类型,我们可以模拟出一个伪类,虽然很麻烦,但是也凑活着能用.
#include iostreamusing namespace std;struct Student
{char name[64];int age;
};void Print_Student(struct Student *ptr)
{printf(Name: %s -- Age: %d \n, ptr-name, ptr-age);
}int main(int argc, char *argv[])
{struct Student stu;strcpy(stu.name, lyshark);stu.age 23;Print_Student(stu);system(pause);return 0;
}定义简单的类: 接着我们来定义一个真正的Student类,并调用成员函数实现对数据成员的输出.
#include iostream
#include stringusing 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;
}定义构造/析构函数: 构造函数通常用于初始化类中的数据成员,析构函数则主要负责对类的清理工作.
#include iostream
#include stringusing namespace std;class Student
{
public:int uid;char *name;int age;public:Student() { cout init .. endl; } // 定义无参构造函数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 stringusing 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) // 拷贝构造函数{this-uid ptr.uid; // 实现将传入的参数this-name ptr.name; // 拷贝到新的类中this-age ptr.age; // 此时两个类就具有相同属性了cout ptr clone endl;}
};int main(int argc, char *argv[])
{Student stu1(1001, admin, 22);// 如下开辟新对象stu2 - 将stu1中的数据拷贝到stu2Student stu2(stu1);cout stu2.name endl;cout stu2.age endl;// 第二种拷贝方式Student stu3 Student(stu1);cout stu3.name endl;system(pause);return 0;
}使用浅/深拷贝: 浅拷贝主要是对数据成员表层的拷贝,这种拷贝容易出现问题,而深拷贝则是完全对数据的复制.
先来看下面这段代码,该代码就是一个典型的浅拷贝,当代码Student stu2(stu1);拷贝完成后,在执行析构函数时,由于是浅拷贝,数据成员共用一片内存区域,而析构函数则执行了两次,第一次释放后,第二次释放内存则出现冲突的情况.
#include iostreamusing namespace std;class Student
{
public:char * m_name;int m_age;public:Student(char * name, int age){this-m_age age;this-m_name (char *)malloc(strlen(name) 1);strcpy(this-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 iostreamusing namespace std;class Student
{
public:char * m_name;int m_age;public:Student() { }Student(char * name, int age){this-m_age age;this-m_name (char *)malloc(strlen(name) 1);strcpy(this-m_name, name);}~Student(){if (m_name ! NULL)free(m_name);}Student(const Student ptr) // 定义拷贝构造函数{this-m_age ptr.m_age;this-m_name (char *)malloc(strlen(ptr.m_name) 1);strcpy(this-m_name, ptr.m_name); // 深层拷贝}
};int main(int argc, char *argv[])
{Student stu1(lyshark, 25);Student stu2(stu1);system(pause);return 0;
}构造函数初始化列表: 定义构造函数也可使用初始化列表的形式来对数据赋值,这种方式很简洁,适合简单的构造函数使用.
#include iostreamusing namespace std;class Student
{
public:char * m_name;int m_age;public:// 无参数构造函数的写法Student(){ }// 有参构造函数,使用初始化列表Student(char * x, int y) :m_name(x), m_age(y){}// 普通函数也可写成一行void Show(){ cout this-m_name endl; }
};int main(int argc, char *argv[])
{Student stu1(lyshark,24);stu1.Show();system(pause);return 0;
}new 动态对象创建: 该关键字可用来实例化类,它可以自动分配初始化空间,开辟到堆中,并且自动来维护释放,非常方便.
#include iostreamusing namespace std;class Student
{
public:char * m_Str;public:Student() { cout 默认构造调用 endl; }~Student() { cout 默认析构调用 endl; }
};int main(int argc, char *argv[])
{// malloc 返回 void* 还必须要强转Student stu1; // 在栈上开辟的空间// 所有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;
}静态数据成员: 静态成员变量,无论建立多少个对象,都只有一个静态数据的拷贝,所有对象都共享这个静态数据.
#include iostreamusing namespace std;class Student
{
public:// 静态成员变量必须在类内声明,在类外对其进行初始化static int m_number; // 定义静态成员变量static char * m_name; // 定义静态成员变量
};int Student::m_number 100; // 类外初始化
char *Student::m_name lyshark; // 类外初始化静态成员变量int main(int argc, char *argv[])
{Student stu1, stu2;// 此处如果对stu1中的静态变量修改后,stu2也会受到影响,两个是共享的数据源stu1.m_number 200;cout stu1.m_number stu1.m_name endl;cout stu2.m_number stu2.m_name endl;cout 通过类名直接访问: Student::m_number endl;cout 通过类名直接访问: Student::m_name endl;system(pause);return 0;
}静态成员函数: 静态成员函数,不可以访问普通的成员变量,仅可以访问通过static修饰的,静态成员变量.
#include iostreamusing namespace std;class Student
{
public:static int m_number;public:static void Display(){cout m_number endl;cout hello lyshark endl;}
};int Student::m_number 100; // 类外初始化int main(int argc, char *argv[])
{Student stu1, stu2;stu1.Display(); // 调用两个函数返回值相同stu2.Display(); // 两个成员函数就是一个system(pause);return 0;
}关于this指针: 该指针是默认存在于类中的,由编译器维护,this指针指向被调用的成员函数所属的对象.
#include iostream
#include stringusing 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; // 年龄相同elsecout 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;
}空指针访问成员函数: 如下定义空指针,并尝试使用空指针访问类,那么如果类中没有判断空指针的语句,则程序会崩溃.
#include iostreamusing namespace std;class Person
{
public:int m_age;public:void show() { cout person show endl; }void show_age() // 此处如果没有if判断,则程序会报错{if (this NULL) // 防止使用空指针访问return;cout show: m_age endl;}
};int main(int argc, char *argv[])
{// show_age() 默认会加上 this -- 那么如果传递空指针则失败// 代码接收空指针,会溢出,说以在类中进行判断,可以防止空指针错误Person *ptr NULL;ptr-show(); // 这个可以ptr-show_age(); // 不可以system(pause);return 0;
}定义常函数/常对象: 使用Const修饰的成员函数,则是常函数,如果用来修饰对象则是常对象,两者均不可直接修改.
#include iostreamusing 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// this-m_x 200; 常函数无法直接修改cout this-m_x endl;}
};int main(int argc, char *argv[])
{// 常函数的调用Person per1;per1.showInfo();// 定义常对象,常对象不允许修改数据,只能调用const Person per2;per2.showInfo();system(pause);return 0;
}友元函数的定义: 将全局函数定义为友元函数,让外部函数,可以访问特定的类内部的私有数据.
#include iostream
#include stringusing namespace std;class Student
{ // 定义友元函数 -- 让goodGay 可以访问我的私有属性friend void goodGay(Student *ptr);
private:string m_badRoom; // 私有的卧室string m_sittingRoom; // 私有的客厅public:Student(){this-m_sittingRoom 客厅;this-m_badRoom 卧室;}
};// 全局函数,我想让他能访问到私有的卧室
void goodGay(Student *ptr)
{cout 访问我的客厅: ptr-m_badRoom endl;cout 访问我的卧室: ptr-m_sittingRoom endl;
}int main(int argc, char *argv[])
{Student *stu new Student;goodGay(stu);system(pause);return 0;
}友元类的定义: 我们除了可以让全局函数访问类中的特定私有数据外,也可以让一个对象实现相同的功能.
#include iostreamusing 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(){// 此时Student中的Display()函数可以访问Teacher类中的私有数据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;
}类实现单例模式: 所谓单例模式就是说一个类只能实例化出一个对象,不论你new创建多少次,始终让其保证只有一个对象,这样就可以防止冲突的情况发生,如下是打印机案例的演示,一个公司可能只有一个打印机,这个打印机必须要单一.
#include iostreamusing namespace std;class Printer
{
private:static Printer * single_Print;static int count;private:Printer(){ };Printer(const Printer ptr);public:static Printer * getInstance(){count count 1;return single_Print;}static void PrintText(char * text){cout Printer ready: count text endl;}
};// 初始化打印机中的静态数据成员
Printer * Printer::single_Print new Printer;
int Printer::count 0;int main(int argc, char *argv[])
{// 拿到打印机对象指针,后期通过该指针操作数据Printer * ptr Printer::getInstance();ptr-getInstance();ptr-getInstance(); // 每次调用都会1ptr-PrintText( count); // 调用打印机system(pause);return 0;
}本文作者 王瑞 本文链接 https://www.lyshark.com/post/f7c7b776.html 版权声明 本博客所有文章除特别声明外均采用 BY-NC-SA 许可协议。转载请注明出处