c++面向对象 封装 及其部分基础
在c++中,定义类我们通常使用class关键字(c++中struct也可以定义类)。{}中为类的主体,其中的内容称之为类的成员:类中的变量被称为成员变量,类中的函数被称为成员函数。用类创建对象的过程,我们也称之为实例化。public://成员函数(默认为inline)private://成员变量int main()return 0;
1.1、类的定义
在c++中,定义类我们通常使用class关键字(c++中struct也可以定义类)。{}中为类的主体,其中的内容称之为类的成员:类中的变量被称为成员变量,类中的函数被称为成员函数。用类创建对象的过程,我们也称之为实例化。
class Student
{
public:
//成员函数(默认为inline)
void printname(string name)
{
cout << name << endl;
}
private:
//成员变量
string name;
};
int main()
{
Student s1("zs");
s1.printname();
return 0;
}
1.2、访问限定符
在c++中,所有的 成员变量 和 成员函数 都有访问权限,即能不能访问该类中的成员变量和成员函数。
···
用来控制访问权限的 关键字 有public、protected和private,他们分别表示公有、受保护、私有的。
public:
可以被该类中的函数,子类的函数,及其友元函数访问,也可以由该类的对象访问。
protected:
可以被该类中的函数,子类的函数,及其友元函数访问,但不能被该类的对象访问。
private:
只能由类中的函数及其友元函数访问,不能被其他任何访问,该类对象也不能访问。
*使用friend修饰的类外函数叫做友元函数(需要放在类中声明)*
class Student
{
public:
int a1 = 100;
protected:
int a2 = 200;
private:
int a3 = 300;
public:
void print()
{
cout<<"v1="<<v1<<endl;
cout<<"v2="<<v2<<endl;
cout<<"v3="<<v3<<endl;
}
};
int main()
{
Student s1
s1.print();
s1.v1=999;
s1.v2=888;//报错:对象不能访问受保护的成员变量
s1.v3=111;//报错:对象不能访问私有的的成员变量
return 0;
}
1.3、this关键字
在c++中this是一个关键字,也是一个const指针,它指向当前对象(也就是正在使用的对象),通过它可以访问当前对象的所有成员。
···
this只能在成员函数内部使用,用在其他地方没有意义,也是非法的。只有当对象被创建后this才有意义,因此不能在static成员函数中使用。
class Student
{
public:
Student(string name, int age)
{
this->name = name;
this->age = age;
}
void show()
{
cout << "this->" << this << endl;
}
string name;
int age;
};
int main()
{
Student s1("za", 12);
s1.show();
cout << "s1->" << &s1 << endl;
Student s2("ejj", 22);
s2.show();
cout << "s2->" << &s2 << endl;
return 0;
}
1.4、构造函数与拷贝构造函数
创建一个类时,会自动添加一个跟类名一样的函数,该函数没有任何返回值,且不做任何操作,该函数被称为构造函数,每当创建一个类的实例对象时,c++解释器都会自动调用它。
···
虽然是默认没有参数,但我们没说不能有,我们可以重写该函数,为其设置多个参数,但若不进行传参的话就会调用默认的无参数的构造函数。此处我们可以给他默认值,这样我们就可以做到只用写一个带参的构造函数且实例化的时候也可以不传参。
···
拷贝构造函数只有一个参数,参数类型是本类的引用
参数可以是const引用,也可以是非const引用。一般使用前者,这样既可以以常量对象作为参数又可以以非常量对象作为参数去初始其他对象,一个类中写两个复制构造函数对应不同的参数引用也是可以的。若类的设计者不写复制构造函数,编译器就会自动生成复制构造函数。
*默认构造函数不一定存在,但拷贝构造函数总是存在*
class Student
{
public:
//Student()
//{
// cout << "student xm" << endl;
//}
Student(string name = "xxx", int age)
{
cout << name << endl;
cout << "student method" << endl;
}
};
class Complex
{
public:
double real, imag;
Complex(double r, double i)
{
real = r;
imag = i;
}
Complex(const Complex& c)
{
real = c.real;
imag = c.imag;
cout << "我被调用了" << endl;
}
};
int main()
{
Student s1(30);
Student stu(20);
Complex c1(1,2);
Complex c2(c1);//使用复制构造函数初始化
cout << c2.real << " " << c2.imag;
return 0;
}
1.5、析构函数和动态创建对象
在类被销毁时,系统还提供了一个析构函数,用来做一些清理工作,比如释放分配的内存,关闭打开的文件等,同样,其也是系统自身调用
析构函数没有参数,不能被重载,因此一个类只能有一个析构函数,若没有,系统则会自动生成
···
c++中解决动态内存分配的方案是把创建一个对象所需的操作都结合在一个称为new的运算符里。当new创建一个对象时,它就在堆里为对象分配内存并调用构造函数完成初始化。其有点类似于c里的malloc及其变种等。但c的动态内存分配太麻烦且可能申请内存失败,很容易令人混淆。
new表示式的反面是delete表示式,其等同于free。
class Student
{
public:
Student()
{
cout << "call student" << endl;
}
~Student()
{
cout << "call ~ student" << endl;
}
};
int main()
{
Student s1(30);
//动态创建对象
Person *p1 = new Person;
delete p1;
return 0;
}
1.6、静态成员变量和静态成员函数
在c++中,类的静态成员可以实现多个 对象 之间的数据共享,因此是类的所有对象中共享的成员,而不是某个对象的成员,这样就节省了内存,也能提高效率。
*在访问类的静态成员时,既可以使用类名访问也可以使用对象名来访问*
class Student
{
public:
Student(string name, int age)
{
this->name = name;
this->age = age;
}
static void sayHello()
{
cout << "this is sayHello()" << course << endl;
}
void sayHi()const
{
cout << "sayHi()" << this->course << this->name << this->age << endl;
}
public:
string name;
int age;
static string course;
};
//两个冒号为类作用域操作符,可以理解为“取”
string Student::course = "c++";//定义后"必须"要在全局初始化,最前面的(type)一定要有,没有就报错
int main()
{
Student s1;
cout << "course=" << Student::course <<endl;
return 0;
}
1.7、友元类
可以使用friend定义一个友元类,如果一个类是另一个类的友元类,友元类可以访问类的所有私有的成员(若定义在使用后,使用前需声明,如以下)
//友元类
class Teacher;
class Student
{
private:
string sname;
int sage;
public:
Student(string name, int age)
{
this->sname = name;
this->sage = age;
}
void stu_print(Teacher& t);
};
class Teacher
{
private:
string tname;
int tage;
public:
Teacher(string name, int age)
{
this->tname = name;
this->tage = age;
}
friend class Student;
};
void Student::stu_print(Teacher& t)
{
cout << this->sname << endl;
cout << t.tname << endl;
}
int main()
{
Student s1("xiaoming", 22);
Teacher t1("tea", 45);
s1.stu_print(t1);
return 0;
}
1.8、运算符重载
此处我感觉不用太说明,算得上新东西就一个operater,直接上代码吧
class Student
{
public:
string name;
int age;
Student(string name, int age)
{
this->age = age;
this->name = name;
}
void operator = (const Student& t)
{
this->name = t.name;
this->age = t.age;
}
bool operator>(Student& t)
{
if (this->age > t.age)
{
return 1;
}
else
{
return 0;
}
}
bool operator<=(Student& t)
{
if (this->age <= t.age)
{
return 1;
}
else
{
return 0;
}
}
void printInfo()
{
cout << this->name << " " << this->age << endl;
}
};
class Complex
{
public:
double r, i;
Complex(){}
Complex(double r, double i)
{
this->i = i;
this->r = r;
}
Complex operator+(Complex& c)
{
Complex c2;
c2.r = this->r + c.r;
c2.i = this->i + c.i;
return c2;
}
Complex operator-(Complex& c)
{
Complex c2;
c2.r = this->r - c.r;
c2.i = this->i - c.i;
return c2;
}
void print()
{
cout << this->r << " " << this->i << endl;
}
};
const int SIZE = 5;
class SafeArr
{
public:
int arr[SIZE];
SafeArr()
{
register int i = 0;
for (; i < SIZE; i++)
{
arr[i] = i;
}
}
int operator[](int i)
{
if (i > SIZE)
{
cout << "下标越界" << endl;
return -1;
}
else
{
return arr[i];
}
}
};
int main()
{
Student s1("zs", 20), s2("ww", 30);
s1.printInfo();
s2 = s1;
s2.printInfo();
if (s1 <= s2)
{
cout << "s1 <= s2" << endl;
}
Complex c1(11, 12), c2(10, 11), c3, c4;
c3 = c1 + c2;
c3.print();
c4 = c1 - c2;
c4.print();
return 0;
}
感谢大家观看萌新的第一篇博客
更多推荐


所有评论(0)