C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。
使用结构体定义类: 其实使用C语言中的结构体类型,我们可以模拟出一个伪类,虽然很麻烦,但是也凑活着能用.
#include <iostream>
using 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 <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; }
|
定义构造/析构函数: 构造函数通常用于初始化类中的数据成员,析构函数则主要负责对类的清理工作.
#include <iostream> #include <string>
using 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 <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) { 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);
Student 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 <iostream>
using 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 <iostream>
using 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 <iostream>
using 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 <iostream>
using namespace std;
class Student { public: char * m_Str;
public: Student() { cout << "默认构造调用" << endl; } ~Student() { cout << "默认析构调用" << endl; } };
int main(int argc, char *argv[]) { Student stu1;
Student *stu2 = new Student; delete stu2;
Student *pArray = new Student[10];
pArray[0].m_Str = "lyshark"; cout << pArray[0].m_Str << endl; delete[] pArray;
system("pause"); return 0; }
|
静态数据成员: 静态成员变量,无论建立多少个对象,都只有一个静态数据的拷贝,所有对象都共享这个静态数据.
#include <iostream>
using 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.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 <iostream>
using 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 <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; }
|
空指针访问成员函数: 如下定义空指针,并尝试使用空指针访问类,那么如果类中没有判断空指针的语句,则程序会崩溃.
#include <iostream>
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();
system("pause"); return 0; }
|
定义常函数/常对象: 使用Const
修饰的成员函数,则是常函数,如果用来修饰对象则是常对象,两者均不可直接修改.
#include <iostream>
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 { 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 <string>
using namespace std;
class Student { 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 <iostream>
using namespace std;
class Teacher { friend class Student;
private: char * m_school; char * m_class;
public: Teacher() { this->m_school = "中心小学"; this->m_class = "一年级二班"; } };
class Student { private: Teacher *ptr;
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; }
|
类实现单例模式: 所谓单例模式就是说一个类只能实例化出一个对象,不论你new创建多少次,始终让其保证只有一个对象,这样就可以防止冲突的情况发生,如下是打印机案例的演示,一个公司可能只有一个打印机,这个打印机必须要单一.
#include <iostream>
using 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(); ptr->PrintText(" count");
system("pause"); return 0; }
|