类是面向对象语言特有的语法,在面向对象语言中所有的变量和函数统称为对象,并且类里面可以对象。
class ClassName
{
// 类体:由成员函数和成员变量组成
void Init();
int a;
};
//class为定义类的关键字,ClassName为类名,{}中为类的主题,注意类定义结束时后面分号不能省略。
//类中的内容称为类的成员:类的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。
// 成员函数声明定义都在类中
class xty
{
public:
void Print()
{
cout << "defined in class" << endl;
}
private:
int a;
int b;
};
// .h文件
class xty2
{
public:
//声明
void Print();
private:
int a;
int b;
};
// .cpp定义
void xty2::Print()
{
cout << "defined in class" << endl;
}
工程项目实践中,更推荐声明和定义分开来处理。
有声明说明语法没问题,可以编译过;有定义,链接的时候就能根据符号表找到地址了,可以链接过
访问限定符:1.public(公有);2.protected(保护);3.private(私有)
class Xty
{
public:
void Print()
{
cout << "defined in class" << endl;
}
private:
int a = 10;
int b;
int c;
};
int main()
{
//声明xp对象
Xty xp;
xp.a = 10; //报错,因为a 为私有,所以对xp.a不可访问
int z = xp.a; //报错,因为a 为私有,所以对xp.a不可访问
xp.Print(); //可以运行,Print成员函数为公有,因此可以在类外面访问
return 0;
}
这样做的目的是:将成员变量设置为私有,将成员函数设置为公有,防止外部成员滥改成员变量。
C++具有三大特性:继承、封装和多态。
将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开的接口来和对象进行交互。封装本质上是一种管理,让用户更安全更方便的使用类。
类定义了一个新的作用域,类的所有成员都在类的作用域中。在类外定义成员时,需要使用::域作用限定符。
class Xty
{
public:
void Print();
private:
int a = 10;
int b;
int c;
};
//在类外面定义成员时,需加上域名,来说明Print是属于Xty这个域里面的
void Xty::Print()
{
cout << "hello world!" << endl;
}
用类型创建类称为类的实例化。
class Xty
{
public:
void Print();
int a;
int b;
int c;
};
//在类外面定义的成员函数
void Xty::Print()
{
cout << "hello world!" << endl;
}
int main()
{
//Xty的类创建出xp的对象
Xty xp;
//是给xp的对象赋值,而不是给类赋值
xp.a = 10;
xp.b = 20;
xp.Print();
return 0;
}
编译器是如何存储对象的呢?
先看一段代码示例:
//类中既有成员变量又有成员函数
class X1
{
public:
void Print()
{
cout << "hello world" << endl;
}
private:
char a;
};
//类中只有成员变量
class X2
{
private:
int a;
};
//类中什么也没有
class X3
{
};
int main()
{
X1 x1;
X2 x2;
X3 x3;
cout<<"x1 : " << sizeof(x1) << endl; // 1
cout<<"x2 : " << sizeof(x2) << endl; // 4
cout<<"x1 : " << sizeof(x3) << endl; // 1
return 0;
}
观察可以看出,对象的成员变量占用存储空间,而成员函数不占用对象的空间,并且类对象中什么都没有时,给1B来占位,标识该对象存在。
事实上:成员变量和成员函数是分开存储的,只有成员变量占用对象的存储空间,而该类的所有对象的成员函数,同统一存储在公共代码区,并且所有对象共用该代码。
先看下面一段代码:
class Time
{
public:
void Init(int h, int min, int s)
{
_h = h;
_min = min;
_s = s;
}
void Print()
{
cout << _h << ":" << _min << ":" << _s << endl;
}
private:
int _h;
int _min;
int _s;
};
int main()
{
Time t1;
Time t2;
t1.Init(10, 20, 3);
t2.Init(5, 10, 1);
t1.Print(); // 10:20:3
t2.Print(); // 5:10:1
}
因为成员函数在公共区,而成员函数有Print函数和Init函数,C++是如何知道当调用t1.Init()函数时,怎么知道我是要使用t1对象,还是要使用t2对象的呢?
答:C++编译器给每个“非静态的成员函数”增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要传递,编译器自动完成,这个指针就是“this指针”。
this指针是存在的,只不过是编译器自动帮我们完成的,我们可使用,也可以不使用
实参和形参不能显示的传递和接受this指针,会报错(不能编译通过)。如下图:
但是可以在成员函数内部使用this指针(可以编译通过),如下图: